'use strict';
var https = require('https');
var util = require('util');
var EventEmitter = require('events');
module.exports = TelegramClient;
/**
* Construct a telegram bot client
* @class
* @extends EventEmitter
* @param {string} token - Telegram bot api token
* @param {boolean} [generateMethods=false] - generate named properties for api methods (not recommended)
* @param {Object} [extraOptions={}] - extra options to be applied to to https.request
*/
function TelegramClient(token, generateMethods, extraOptions) {
EventEmitter.call(this);
this.token = token;
this.extraOptions = (typeof extraOptions === 'undefined') ? {} : extraOptions;
if (generateMethods === true) {
var telegram = this;
require('./methods').forEach(function(method) {
telegram[method] = function(args, cb) {
return telegram.request(method, args, cb);
};
});
}
}
util.inherits(TelegramClient, EventEmitter);
/**
* @callback TelegramClient~requestCallback
* @param {Error} err
* @param {Object} response
*/
/**
* Send an api request to telegram
* @param {string} method - API method to call
* @param {Object} [args={}] - API call arguments
* @param {TelegramClient~requestCallback} [cb] - The callback that handles the response
*/
TelegramClient.prototype.request = function(method, args, cb) {
if (!args) {
args = {};
}
if (!cb) {
cb = function() { };
}
var argString = JSON.stringify(args);
var options = {
hostname: 'api.telegram.org',
port: '443',
path: '/bot' + this.token + '/' + method,
headers: {
'content-type': 'application/json',
'content-length': Buffer.byteLength(argString)
},
timeout: 1200
};
Object.assign(options, this.extraOptions);
var request = https.request(options, function(res) {
res.setEncoding('utf8');
var data = '';
res.on('data', function(chunk) { data += chunk; });
res.on('end', function() {
var result = null;
try {
result = JSON.parse(data);
} catch (e) {
console.log('warning! non-json result returned');
}
if (result !== null) {
if (result.ok === true) {
cb(null, result.result);
} else if (result.description) {
cb('api returned failed ' + result.description);
} else {
cb('api returned failed with no description');
}
} else {
cb('api returned invalid json');
}
});
});
request.on('timeout', function() {
console.log('timed out !!!!!!!!!');
cb('timed out');
});
request.on('error', function(err) {
console.log(err);
cb('got other error');
});
request.write(JSON.stringify(args));
request.end();
};
/**
* Update event
* @event TelegramClient#update
* @type {object}
*/
/**
* Poll for updates. Updates are emitted as events
* @param {string[]} allowedUpdates - array of updates to poll for
* @param {number} interval - polling interval
* @param {boolean} [deleteWebhook=false] - delete any previously set webook (not implemented)
* @fires TelegramClient#update
*/
TelegramClient.prototype.poll = function(allowedUpdates, interval, deleteWebhook) {
this.allowedUpdates = allowedUpdates;
var updateId = -2;
if (this.polling) {
return;
}
if (!interval) {
interval = 5000;
}
var telegram = this;
this.polling = true;
setInterval(function() {
var args = {
offset: updateId,
allowed_updates: telegram.allowedUpdates
};
telegram.request('getUpdates', args, function(err, result) {
if (err) {
console.log('poll failed ' + err);
return;
}
console.log(result);
result.forEach(function(update) {
updateId = update.update_id + 1;
telegram.emit('update', update);
});
});
}, interval);
};
/**
* Set a webhook to listen for updates. Self signed certificates are not supported. (not implemented yet)
* @param {string[]} allowedUpdates - array of updates to poll for
* @param {boolean} [setWebhook=false] - configure telegram to set the webhook with the given url
* @param {string} [url] - url for telegram to send updates to
*/
TelegramClient.prototype.listen = function(allowedUpdates, setWebhook, url) {
};