Telegram Bot Random Images (How to send random images with Telegram-Bot) - random

const TeleBot = require('telebot');
const bot = new TeleBot({
token: 'i9NhrhCQGq7rxaA' // Telegram Bot API token.
});
bot.on(/^([Hh]ey|[Hh]oi|[Hh]a*i)$/, function (msg) {
return bot.sendMessage(msg.from.id, "Hello Commander");
});
var Historiepics = ['Schoolfotos/grr.jpg', 'Schoolfotos/boe.jpg',
'Schoolfotos/tobinsexy.jpg'];
console.log('Historiepics')
console.log(Math.floor(Math.random() * Historiepics.length));
var foto = Historiepics[(Math.floor(Math.random() * Historiepics.length))];
bot.on(/aap/, (msg) => {
return bot.sendPhoto(msg.from.id, foto);
});
bot.start();
The result I'm getting from this is just one picture everytime, but if I ask for another random picture it keeps showing me the same one without change.

I recently figured this out, so I'll drop an answer for anyone that runs into this issue.
The problem is with Telegram's cache. They cache images server side so that they don't have to do multiple requests to the same url. This protects them from potentially getting blacklisted for too many requests, and makes things snappier.
Unfortunately if you're using an API like The Cat API this means you will be sending the same image over and over again. The simplest solution is just to somehow make the link a little different every time. This is most easily accomplished by including the current epoch time as a part of the url.
For your example with javascript this can be accomplished with the following modifications
bot.on(/aap/, (msg) => {
let epoch = (new Date).getTime();
return bot.sendPhoto(msg.from.id, foto + "?time=" + epoch);
});
Or something similar. The main point is, as long as the URL is different you won't receive a cached result. The other option is to download the file and then send it locally. This is what Telebot does if you pass the serverDownload option into sendPhoto.

Related

How to get query sys_id of current.sys_id Service Portal (ServiceNow)

I have a question regarding a small issue that I'm having. I've created a widget that will live on the Service Portal to allow an admin to Accept or Reject requests.
The data for the widget is pulling from the Approvals (approval_approver) table. Under my GlideRecord, I have a query that checks for the state as requested. (Ex. addQuery('state', 'requested'))
To narrow down the search, I tried entering addQuery('sys_id', current.sys_id). When I use this query, my script breaks and I get an error on the Service Portal end.
Here's a sample of the GlideRecord script I've written to Accept.
[//Accept Request
if(input && input.action=="acceptApproval") {
var inRec1 = new GlideRecord('sysapproval_approver');
inRec1.addQuery('state', 'requested');
//inRec1.get('sys_id', current.sys_id);
inRec1.query();
if(inRec1.next()) {
inRec1.setValue('state', 'Approved');
inRec1.setValue('approver', gs.getUserID());
gs.addInfoMessage("Accept Approval Processed");
inRec1.update();
}
}][1]
I've research the web, tried using $sp.getParameter() as a work-around and no change.
I would really appreciate any help or insight on what I can do different to get script to work and filter the right records.
If I understand your question correctly, you are asking how to get the sysId of the sysapproval_approver record from the client-side in a widget.
Unless you have defined current elsewhere in your server script, current is undefined. Secondly, $sp.getParameter() is used to retrieve URL parameters. So unless you've included the sysId as a URL parameter, that will not get you what you are looking for.
One pattern that I've used is to pass an object to the client after the initial query that gets the list of requests.
When you're ready to send input to the server from the client, you can add relevant information to the input object. See the simplified example below. For the sake of brevity, the code below does not include error handling.
// Client-side function
approveRequest = function(sysId) {
$scope.server.get({
action: "requestApproval",
sysId: sysId
})
.then(function(response) {
console.log("Request approved");
});
};
// Server-side
var requestGr = new GlideRecord();
requestGr.addQuery("SOME_QUERY");
requestGr.query(); // Retrieve initial list of requests to display in the template
data.requests = []; // Add array of requests to data object to be passed to the client via the controller
while(requestsGr.next()) {
data.requests.push({
"number": requestsGr.getValue("number");
"state" : requestsGr.getValue("state");
"sysId" : requestsGr.getValue("sys_id");
});
}
if(input && input.action=="acceptApproval") {
var sysapprovalGr = new GlideRecord('sysapproval_approver');
if(sysapprovalGr.get(input.sysId)) {
sysapprovalGr.setValue('state', 'Approved');
sysapprovalGr.setValue('approver', gs.getUserID());
sysapprovalGr.update();
gs.addInfoMessage("Accept Approval Processed");
}
...

How do I get a random beer every time I reload the page?

I'm trying to fetch a random beer and a list of 20 beers from the Punk Beer API , and display it on the page. However, for some reason, the API with the random url kept returning the same beer (id:221, name: Blitz Series).I'm confused why it's not a different beer each time I reload the page.
Here's my code :
componentDidMount(){
const root_api = "https://api.punkapi.com/v2/";
var self = this;
axios.all([
axios.get(`${root_api}/beers/random`),
axios.get(`${root_api}beers?page=2&per_page=20`)
])
.then(axios.spread(function (randomBeerResponse, beerListResponse) {
self.setState({randomBeer:randomBeerResponse.data[0]})
self.setState({beers:beerListResponse.data})
}));
}
You are adding const root_api = "https://api.punkapi.com/v2/"; to axios.get(${root_api}/beers/random) which creates "https://api.punkapi.com/v2//beers/random"
As you can see there are two slashes "//" between v2 and beers and that leads to returning the same beer over and over again.
Write axios.get(${root_api}beers/random) instead and the problem will resolve.
The whole code in correct format would be:
componentDidMount(){
const root_api = "https://api.punkapi.com/v2/";
var self = this;
axios.all([
axios.get(`${root_api}beers/random`),
axios.get(`${root_api}beers?page=2&per_page=20`)
])
.then(axios.spread(function (randomBeerResponse, beerListResponse) {
self.setState({randomBeer:randomBeerResponse.data[0]})
self.setState({beers:beerListResponse.data})
}));
}
As a side-note, when you're dealing with API, you should test the API outside of your program with an API testing/development tool like Postman.
The problem here has nothing to do with React. It's just the API.
Add a header in your axios request : headers: {"Pragma", "no-cache"};
This tells browser to make a new call everytime and not memorize the previous request.

how to use xml file in ajax chat?

I want to build a website like Facebook style, and for start i am building a chat system using ajax. For now, all the messages that are sent to the chat system are saved in a xml file which looks like this:
<messages>
<message from="jhon" time="2:00">Hi!</message>
</messages>
My question is if it is fine to use the xml file like i do here, or a database is the solution. Can someone explain to me how to use xml in the right way also in the chat or a messages system if it is necessary at all?
Thank you!
I made an exercise (for school) that worked in a simular way:
<post>
<time>15:25</time>
<name>myUserName</name>
<message>testbla</message>
</post>
I used a PHP-script (provided by the teacher) to write in the file (in the format like before) each time there is a new message being sent by the user. While it was working well, there were a few problems I encountered:
In order to keep the chat updated, I had to reload the chat 3600 times per hour. This is no problem. However, because I was using XML, I had to download the file 3600x per hour, which is definitely not an elegant solution; with only a few messages, the site consumed about 20-40 MB data each hour. (you do the math!)
There were also issues with the special chars that conflicted to XML: <, > and &. I had to either escape them, remove them from the user input OR use CDATA to prevent XML from crashing due to syntax errors. (XML is very sensitive for this!) Additional difficulty was to prevent that others could send bad code. Generally, try to eliminate this while updating your XML-file.
With the above in mind, I would recommend searching for a more elegant solution than XML; JSON might be lighter to handle. Alternatively, MYSQL/PHP allow you to send only the last messages, so you don't have to send the whole file over and over again. (I don't have any PHP/MYSQL-expertise at this moment, so I cannot help you with that right now)
You asked how you could make your XML-chat happen. To give you some direction, I will give you some snippets of my code (with jQuery):
/* this function gets chat logs from XML and manipulate the content to a
div used for the chat-content. It is being evaluated each second by
an interval that calls the function each 1000 ms. (not included in this code) */
function getChatLogs() {
var chatLogs = "";
$.ajax({
url: "chat_log.xml",
success: function(data) {
$(data).find("post").each(function() {
var timeMessage = $(this).find("time").text();
var nameSender = $(this).find("name").text();
var contentMessage = $(this).find("message").text();
chatLogs += "<article><time>" + timeMessage + "</time> <strong>" + nameSender + "</strong> <p>" + contentMessage+ "</p></article>";
});
$("#chat").html(chatLogs);
}
});
}
/* this function handles messages being send by the user */
function sendInput(keyCode) {
if(keyCode === 13 && $("#post").val() != "") {
var name = localStorage.getItem("username"); // I used localstorage fo username
var time = currentTime();
var message = $("#post").val();
$.ajax({
type: "POST",
url: "save.php",
data: {"name": name, "time": time, "message": message},
success: function(data) {
$("#post").val(""); // (clear the chat-input)
}
});
}
}
Bonus tip: you XML-file MUST be well formed. You can easily check if this is the case by opening the XML-file straight in Chrome. If there are issues, it will give an error.

can't seem to get progress events from node-formidable to send to the correct client over socket.io

So I'm building a multipart form uploader over ajax on node.js, and sending progress events back to the client over socket.io to show the status of their upload. Everything works just fine until I have multiple clients trying to upload at the same time. Originally what would happen is while one upload is going, when a second one starts up it begins receiving progress events from both of the forms being parsed. The original form does not get affected and it only receives progress updates for itself. I tried creating a new formidable form object and storing it in an array along with the socket's session id to try to fix this, but now the first form stops receiving events while the second form gets processed. Here is my server code:
var http = require('http'),
formidable = require('formidable'),
fs = require('fs'),
io = require('socket.io'),
mime = require('mime'),
forms = {};
var server = http.createServer(function (req, res) {
if (req.url.split("?")[0] == "/upload") {
console.log("hit upload");
if (req.method.toLowerCase() === 'post') {
socket_id = req.url.split("sid=")[1];
forms[socket_id] = new formidable.IncomingForm();
form = forms[socket_id];
form.addListener('progress', function (bytesReceived, bytesExpected) {
progress = (bytesReceived / bytesExpected * 100).toFixed(0);
socket.sockets.socket(socket_id).send(progress);
});
form.parse(req, function (err, fields, files) {
file_name = escape(files.upload.name);
fs.writeFile(file_name, files.upload, 'utf8', function (err) {
if (err) throw err;
console.log(file_name);
})
});
}
}
});
var socket = io.listen(server);
server.listen(8000);
If anyone could be any help on this I would greatly appreciate it. I've been banging my head against my desk for a few days trying to figure this one out, and would really just like to get this solved so that I can move on. Thank you so much in advance!
Can you try putting console.log(socket_id);
after form = forms[socket_id]; and
after progress = (bytesReceived / bytesExpected * 100).toFixed(0);, please?
I get the feeling that you might have to wrap that socket_id in a closure, like this:
form.addListener(
'progress',
(function(socket_id) {
return function (bytesReceived, bytesExpected) {
progress = (bytesReceived / bytesExpected * 100).toFixed(0);
socket.sockets.socket(socket_id).send(progress);
};
})(socket_id)
);
The problem is that you aren't declaring socket_id and form with var, so they're actually global.socket_id and global.form rather than local variables of your request handler. Consequently, separate requests step over each other since the callbacks are referring to the globals rather than being proper closures.
rdrey's solution works because it bypasses that problem (though only for socket_id; if you were to change the code in such a way that one of the callbacks referenced form you'd get in trouble). Normally you only need to use his technique if the variable in question is something that changes in the course of executing the outer function (e.g. if you're creating closures within a loop).

html5 multiple upload along with ajax

I am trying to use the multiple upload attribute of HTML5 to upload files.
I know it wouldn't work with IE and fall back to single file upload.
also I found some invalid html tag like min max allows opera to do the same.
I am trying to do the following:
The browse button be capable of selecting multiple files.
But the ajax should send files one by one.
My scenario is something like this:
the user selects 5 files and starts the upload . Now the ajax should firstfile send the first file, then second, and so on.
The server side script does something with the file and returns some data.
now as soon as one file upload is completed it must render that part of the result.
So as the user selects images and starts uploading the results come out as soon as each file is uploaded (and not after all the files are uploaded).
I tried something like this :
function handleFiles(files)
{ alert(files.length); //properly returns the number of files selected
for (var i = 0; i < files.length; i++) {
new FileUpload(files[i])
}
}
function FileUpload(file) {
var reader = new FileReader();
var xhr = new XMLHttpRequest();
this.xhr = xhr;
xhr.open("POST", "portfolio/add_media");
reader.onload = function(evt) {
xhr.sendAsBinary(evt.target.result);
};
reader.readAsBinaryString(file);
}
after reading the tutorial at mozilla but I end up with missing params.
. so can some one suggest me a clean solution to this
Some more details :
When I pass a single file ( with no multiple attribute ) my server recieves :
"image"=>[# < ActionDispatch::Http::UploadedFile:0x10d55be8
#tempfile=#< File:C:/Users/Gaurav/AppData/Local/Temp/RackMultipart20110701-1916-2ly4k2-0>,
#headers="Content-Disposition:
form-data; name=\"picture[image][]\";
filename=\"Desert.jpg\"\r\nContent-Type:
image/jpeg\r\n",
#content_type="image/jpeg",
#original_filename="Desert.jpg">]}}
But when I use multiple attribute and send using xhr I am able to get only one file param. How do I get the rest of the params ? esp the action dispatch thingy
You are simply sending the file data to the server, without encoding it in any way. For the server to know how to process it you need to encode your data properly (multipart/form-data encoding). Easiest way is using a FormData object: https://developer.mozilla.org/En/Using_XMLHttpRequest#Sending_files_using_a_FormData_object. Only that instead of data.append("CustomField", "This is some extra data") you would write data.append("file1", event.target.result).

Resources