diff --git a/README.md b/README.md
index 1fb310d..3003c5c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Node.js Telegram Bot API
-[](https://core.telegram.org/bots/api)
+[](https://core.telegram.org/bots/api)
[](https://travis-ci.org/yagop/node-telegram-bot-api)
[](https://ci.appveyor.com/project/yagop/node-telegram-bot-api/branch/master)
[](https://coveralls.io/r/yagop/node-telegram-bot-api?branch=master)
diff --git a/doc/api.md b/doc/api.md
index 47c3d6e..0cd1369 100644
--- a/doc/api.md
+++ b/doc/api.md
@@ -38,6 +38,15 @@ TelegramBot
* [.sendChatAction(chatId, action)](#TelegramBot+sendChatAction) ⇒ Promise
* [.kickChatMember(chatId, userId)](#TelegramBot+kickChatMember) ⇒ Promise
* [.unbanChatMember(chatId, userId)](#TelegramBot+unbanChatMember) ⇒ Promise
+ * [.restrictChatMember(chatId, userId, [options])](#TelegramBot+restrictChatMember) ⇒ Promise
+ * [.promoteChatMember(chatId, userId, [options])](#TelegramBot+promoteChatMember) ⇒ Promise
+ * [.exportChatInviteLink(chatId)](#TelegramBot+exportChatInviteLink) ⇒ Promise
+ * [.setChatPhoto(chatId, photo)](#TelegramBot+setChatPhoto) ⇒ Promise
+ * [.deleteChatPhoto(chatId)](#TelegramBot+deleteChatPhoto) ⇒ Promise
+ * [.setChatTitle(chatId, title)](#TelegramBot+setChatTitle) ⇒ Promise
+ * [.setChatDescription(chatId, description)](#TelegramBot+setChatDescription) ⇒ Promise
+ * [.pinChatMessage(chatId, messageId)](#TelegramBot+pinChatMessage) ⇒ Promise
+ * [.unpinChatMessage(chatId)](#TelegramBot+unpinChatMessage) ⇒ Promise
* [.answerCallbackQuery(callbackQueryId, text, showAlert, [options])](#TelegramBot+answerCallbackQuery) ⇒ Promise
* [.editMessageText(text, [options])](#TelegramBot+editMessageText) ⇒ Promise
* [.editMessageCaption(caption, [options])](#TelegramBot+editMessageCaption) ⇒ Promise
@@ -422,6 +431,142 @@ the group for this to work. Returns True on success.
| chatId | Number
| String
| Unique identifier for the target group or username of the target supergroup |
| userId | String
| Unique identifier of the target user |
+
+
+### telegramBot.restrictChatMember(chatId, userId, [options]) ⇒ Promise
+Use this method to restrict a user in a supergroup.
+The bot must be an administrator in the supergroup for this to work
+and must have the appropriate admin rights. Pass True for all boolean parameters
+to lift restrictions from a user. Returns True on success.
+
+**Kind**: instance method of [TelegramBot](#TelegramBot)
+**See**: https://core.telegram.org/bots/api#restrictchatmember
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chatId | Number
| String
| Unique identifier for the target chat or username of the target supergroup |
+| userId | String
| Unique identifier of the target user |
+| [options] | Object
| Additional Telegram query options |
+
+
+
+### telegramBot.promoteChatMember(chatId, userId, [options]) ⇒ Promise
+Use this method to promote or demote a user in a supergroup or a channel.
+The bot must be an administrator in the chat for this to work
+and must have the appropriate admin rights. Pass False for all boolean parameters to demote a user.
+Returns True on success.
+
+**Kind**: instance method of [TelegramBot](#TelegramBot)
+**See**: https://core.telegram.org/bots/api#promotechatmember
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chatId | Number
| String
| Unique identifier for the target chat or username of the target supergroup |
+| userId | String
| |
+| [options] | Object
| Additional Telegram query options |
+
+
+
+### telegramBot.exportChatInviteLink(chatId) ⇒ Promise
+Use this method to export an invite link to a supergroup or a channel.
+The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+Returns exported invite link as String on success.
+
+**Kind**: instance method of [TelegramBot](#TelegramBot)
+**See**: https://core.telegram.org/bots/api#exportchatinvitelink
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chatId | Number
| String
| Unique identifier for the target chat or username of the target supergroup |
+
+
+
+### telegramBot.setChatPhoto(chatId, photo) ⇒ Promise
+Use this method to set a new profile photo for the chat. Photos can't be changed for private chats.
+The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+Returns True on success.
+
+**Kind**: instance method of [TelegramBot](#TelegramBot)
+**See**: https://core.telegram.org/bots/api#setchatphoto
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chatId | Number
| String
| Unique identifier for the message recipient |
+| photo | stream.Stream
| Buffer
| A file path or a Stream. |
+
+
+
+### telegramBot.deleteChatPhoto(chatId) ⇒ Promise
+Use this method to delete a chat photo. Photos can't be changed for private chats.
+The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+Returns True on success.
+
+**Kind**: instance method of [TelegramBot](#TelegramBot)
+**See**: https://core.telegram.org/bots/api#deletechatphoto
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chatId | Number
| String
| Unique identifier for the message recipient |
+
+
+
+### telegramBot.setChatTitle(chatId, title) ⇒ Promise
+Use this method to change the title of a chat. Titles can't be changed for private chats.
+The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+Returns True on success.
+
+**Kind**: instance method of [TelegramBot](#TelegramBot)
+**See**: https://core.telegram.org/bots/api#setchattitle
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chatId | Number
| String
| Unique identifier for the message recipient |
+| title | String
| New chat title, 1-255 characters |
+
+
+
+### telegramBot.setChatDescription(chatId, description) ⇒ Promise
+Use this method to change the description of a supergroup or a channel.
+The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+Returns True on success.
+
+**Kind**: instance method of [TelegramBot](#TelegramBot)
+**See**: https://core.telegram.org/bots/api#setchatdescription
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chatId | Number
| String
| Unique identifier for the message recipient |
+| description | String
| New chat title, 1-255 characters |
+
+
+
+### telegramBot.pinChatMessage(chatId, messageId) ⇒ Promise
+Use this method to pin a message in a supergroup.
+The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+Returns True on success.
+
+**Kind**: instance method of [TelegramBot](#TelegramBot)
+**See**: https://core.telegram.org/bots/api#pinchatmessage
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chatId | Number
| String
| Unique identifier for the message recipient |
+| messageId | String
| Identifier of a message to pin |
+
+
+
+### telegramBot.unpinChatMessage(chatId) ⇒ Promise
+Use this method to unpin a message in a supergroup chat.
+The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+Returns True on success.
+
+**Kind**: instance method of [TelegramBot](#TelegramBot)
+**See**: https://core.telegram.org/bots/api#unpinchatmessage
+
+| Param | Type | Description |
+| --- | --- | --- |
+| chatId | Number
| String
| Unique identifier for the message recipient |
+
### telegramBot.answerCallbackQuery(callbackQueryId, text, showAlert, [options]) ⇒ Promise
diff --git a/src/telegram.js b/src/telegram.js
index 3d3b609..d78b11a 100644
--- a/src/telegram.js
+++ b/src/telegram.js
@@ -844,6 +844,157 @@ class TelegramBot extends EventEmitter {
return this._request('unbanChatMember', { form });
}
+ /**
+ * Use this method to restrict a user in a supergroup.
+ * The bot must be an administrator in the supergroup for this to work
+ * and must have the appropriate admin rights. Pass True for all boolean parameters
+ * to lift restrictions from a user. Returns True on success.
+ *
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup
+ * @param {String} userId Unique identifier of the target user
+ * @param {Object} [options] Additional Telegram query options
+ * @return {Promise}
+ * @see https://core.telegram.org/bots/api#restrictchatmember
+ */
+ restrictChatMember(chatId, userId, form = {}) {
+ form.chat_id = chatId;
+ form.user_id = userId;
+ return this._request('restrictChatMember', { form });
+ }
+
+ /**
+ * Use this method to promote or demote a user in a supergroup or a channel.
+ * The bot must be an administrator in the chat for this to work
+ * and must have the appropriate admin rights. Pass False for all boolean parameters to demote a user.
+ * Returns True on success.
+ *
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup
+ * @param {String} userId
+ * @param {Object} [options] Additional Telegram query options
+ * @return {Promise}
+ * @see https://core.telegram.org/bots/api#promotechatmember
+ */
+ promoteChatMember(chatId, userId, form = {}) {
+ form.chat_id = chatId;
+ form.user_id = userId;
+ return this._request('promoteChatMember', { form });
+ }
+
+ /**
+ * Use this method to export an invite link to a supergroup or a channel.
+ * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+ * Returns exported invite link as String on success.
+ *
+ * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup
+ * @return {Promise}
+ * @see https://core.telegram.org/bots/api#exportchatinvitelink
+ */
+ exportChatInviteLink(chatId, form = {}) {
+ form.chat_id = chatId;
+ return this._request('exportChatInviteLink', { form });
+ }
+
+ /**
+ * Use this method to set a new profile photo for the chat. Photos can't be changed for private chats.
+ * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+ * Returns True on success.
+ *
+ * @param {Number|String} chatId Unique identifier for the message recipient
+ * @param {stream.Stream|Buffer} photo A file path or a Stream.
+ * @return {Promise}
+ * @see https://core.telegram.org/bots/api#setchatphoto
+ */
+ setChatPhoto(chatId, photo, options = {}) {
+ const opts = {
+ qs: options,
+ };
+ opts.qs.chat_id = chatId;
+ try {
+ const sendData = this._formatSendData('photo', photo);
+ opts.formData = sendData[0];
+ opts.qs.photo = sendData[1];
+ } catch (ex) {
+ return Promise.reject(ex);
+ }
+ return this._request('setChatPhoto', opts);
+ }
+
+ /**
+ * Use this method to delete a chat photo. Photos can't be changed for private chats.
+ * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+ * Returns True on success.
+ *
+ * @param {Number|String} chatId Unique identifier for the message recipient
+ * @return {Promise}
+ * @see https://core.telegram.org/bots/api#deletechatphoto
+ */
+ deleteChatPhoto(chatId, form = {}) {
+ form.chat_id = chatId;
+ return this._request('deleteChatPhoto', { form });
+ }
+
+ /**
+ * Use this method to change the title of a chat. Titles can't be changed for private chats.
+ * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+ * Returns True on success.
+ *
+ * @param {Number|String} chatId Unique identifier for the message recipient
+ * @param {String} title New chat title, 1-255 characters
+ * @return {Promise}
+ * @see https://core.telegram.org/bots/api#setchattitle
+ */
+ setChatTitle(chatId, title, form = {}) {
+ form.chat_id = chatId;
+ form.title = title;
+ return this._request('setChatTitle', { form })
+ }
+
+ /**
+ * Use this method to change the description of a supergroup or a channel.
+ * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+ * Returns True on success.
+ *
+ * @param {Number|String} chatId Unique identifier for the message recipient
+ * @param {String} description New chat title, 1-255 characters
+ * @return {Promise}
+ * @see https://core.telegram.org/bots/api#setchatdescription
+ */
+ setChatDescription(chatId, description, form = {}) {
+ form.chat_id = chatId;
+ form.description = description;
+ return this._request('setChatDescription', { form })
+ }
+
+ /**
+ * Use this method to pin a message in a supergroup.
+ * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+ * Returns True on success.
+ *
+ * @param {Number|String} chatId Unique identifier for the message recipient
+ * @param {String} messageId Identifier of a message to pin
+ * @return {Promise}
+ * @see https://core.telegram.org/bots/api#pinchatmessage
+ */
+ pinChatMessage(chatId, messageId, form = {}) {
+ form.chat_id = chatId;
+ form.message_id = messageId;
+ return this._request('pinChatMessage', { form });
+ }
+
+ /**
+ * Use this method to unpin a message in a supergroup chat.
+ * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
+ * Returns True on success.
+ *
+ * @param {Number|String} chatId Unique identifier for the message recipient
+ * @return {Promise}
+ * @see https://core.telegram.org/bots/api#unpinchatmessage
+ */
+ unpinChatMessage(chatId, form = {}) {
+ form.chat_id = chatId;
+ return this._request('unpinChatMessage', { form });
+ }
+
/**
* Use this method to send answers to callback queries sent from
* inline keyboards. The answer will be displayed to the user as
diff --git a/test/README.md b/test/README.md
index db6a07c..0e5a091 100644
--- a/test/README.md
+++ b/test/README.md
@@ -23,3 +23,4 @@ npm run test
npm run eslint # static-analysis
npm run mocha # mocha tests
```
+Note: The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
\ No newline at end of file
diff --git a/test/data/chat_photo.png b/test/data/chat_photo.png
new file mode 100644
index 0000000..ee0756d
Binary files /dev/null and b/test/data/chat_photo.png differ
diff --git a/test/telegram.js b/test/telegram.js
index 5f445ab..a087423 100644
--- a/test/telegram.js
+++ b/test/telegram.js
@@ -812,8 +812,115 @@ describe('TelegramBot', function telegramSuite() {
describe.skip('#unbanChatMember', function unbanChatMemberSuite() {});
+ describe.skip('#restrictChatMember', function restrictChatMemberSuite() {});
+
+ describe.skip('#promoteChatMember', function promoteChatMemberSuite() {});
+
describe.skip('#answerCallbackQuery', function answerCallbackQuerySuite() {});
+ describe('#exportChatInviteLink', function exportChatInviteLinkSuite() {
+ before(function before() {
+ utils.handleRatelimit(bot, 'exportChatInviteLink', this);
+ });
+ it('should export the group invite link', function test() {
+ return bot.exportChatInviteLink(GROUPID).then(resp => {
+ assert(resp.match(/^https:\/\/t\.me\/joinchat\/.+$/i), 'is a telegram invite link');
+ });
+ });
+ });
+
+ describe('#setChatPhoto', function setChatPhotoSuite() {
+ this.timeout(timeout);
+ before(function before() {
+ utils.handleRatelimit(bot, 'setChatPhoto', this);
+ });
+ it('should set a chat photo from file', function test() {
+ const photo = `${__dirname}/data/chat_photo.png`;
+ return bot.setChatPhoto(GROUPID, photo).then(resp => {
+ assert.equal(resp, true);
+ });
+ });
+ it('should set a chat photo from fs.readStream', function test() {
+ const photo = fs.createReadStream(`${__dirname}/data/chat_photo.png`);
+ return bot.setChatPhoto(GROUPID, photo).then(resp => {
+ assert.equal(resp, true);
+ });
+ });
+ it('should set a chat photo from request Stream', function test() {
+ const photo = request(`${staticUrl}/chat_photo.png`);
+ return bot.setChatPhoto(GROUPID, photo).then(resp => {
+ assert.equal(resp, true);
+ });
+ });
+ it('should set a chat photo from a Buffer', function test() {
+ const photo = fs.readFileSync(`${__dirname}/data/chat_photo.png`);
+ return bot.setChatPhoto(GROUPID, photo).then(resp => {
+ assert.equal(resp, true);
+ });
+ });
+ });
+
+ describe('#deleteChatPhoto', function deleteChatPhotoSuite() {
+ before(function before() {
+ utils.handleRatelimit(bot, 'deleteChatPhoto', this);
+ });
+ it('should delete the chat photo', function test() {
+ return bot.deleteChatPhoto(GROUPID).then(resp => {
+ assert.equal(resp, true);
+ });
+ });
+ });
+
+ describe('#setChatTitle', function setChatTitleSuite() {
+ before(function before() {
+ utils.handleRatelimit(bot, 'setChatTitle', this);
+ });
+ it('should set the chat title', function test() {
+ return bot.setChatTitle(GROUPID, 'ntba test group').then(resp => {
+ assert.equal(resp, true);
+ });
+ });
+ });
+
+ describe('#setChatDescription', function setChatDescriptionSuite() {
+ before(function before() {
+ utils.handleRatelimit(bot, 'setChatDescription', this);
+ });
+ it('should set the chat description', function test() {
+ const random = Math.floor(Math.random() * 1000);
+ const description = `node-telegram-bot-api test group (random: ${random})`;
+ return bot.setChatDescription(GROUPID, description).then(resp => {
+ assert.equal(resp, true);
+ });
+ });
+ });
+
+ describe('#pinChatMessage', function pinChatMessageSuite() {
+ let messageId;
+ before(function before() {
+ utils.handleRatelimit(bot, 'pinChatMessage', this);
+ return bot.sendMessage(GROUPID, 'To be pinned').then(resp => {
+ messageId = resp.message_id;
+ });
+ });
+ it('should pin chat message', function test() {
+ return bot.pinChatMessage(GROUPID, messageId).then(resp => {
+ assert.equal(resp, true);
+ });
+ });
+ });
+
+ describe('#unpinChatMessage', function unpinChatMessageSuite() {
+ before(function before() {
+ utils.handleRatelimit(bot, 'unpinChatMessage', this);
+ });
+ it('should unpin chat message', function test() {
+ return bot.unpinChatMessage(GROUPID).then(resp => {
+ assert.equal(resp, true);
+ });
+ });
+ });
+
describe('#editMessageText', function editMessageTextSuite() {
before(function before() {
utils.handleRatelimit(bot, 'sendMessage', this);