Repository: Yoctol/bottender
Pull request #750 (2020-04-29 09:16:41)

feat: TelegramContext.answerCallbackQuery

codecov-io: # [Codecov](https://codecov.io/gh/Yoctol/bottender/pull/750?src=pr&el=h1) Report
> Merging [#750](https://codecov.io/gh/Yoctol/bottender/pull/750?src=pr&el=desc) into [master](https://codecov.io/gh/Yoctol/bottender/commit/d38f47cafd8eec7141467ae88ad82eae5549f6ed&el=desc) will **increase** coverage by `0.02%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/Yoctol/bottender/pull/750/graphs/tree.svg?width=650&height=150&src=pr&token=JX3EGtxYH3)](https://codecov.io/gh/Yoctol/bottender/pull/750?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #750      +/-   ##
==========================================
+ Coverage   81.33%   81.35%   +0.02%     
==========================================
  Files         108      108              
  Lines        4639     4644       +5     
  Branches     1171     1172       +1     
==========================================
+ Hits         3773     3778       +5     
  Misses        817      817              
  Partials       49       49              
```


| [Impacted Files](https://codecov.io/gh/Yoctol/bottender/pull/750?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [packages/bottender/src/telegram/TelegramContext.ts](https://codecov.io/gh/Yoctol/bottender/pull/750/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy90ZWxlZ3JhbS9UZWxlZ3JhbUNvbnRleHQudHM=) | `53.65% <100.00%> (+0.57%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Yoctol/bottender/pull/750?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Yoctol/bottender/pull/750?src=pr&el=footer). Last update [d38f47c...ff17d76](https://codecov.io/gh/Yoctol/bottender/pull/750?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/packages/bottender/src/telegram/TelegramContext.ts b/packages/bottender/src/telegram/TelegramContext.ts
index cc3d4a17..2021aa79 100644
--- a/packages/bottender/src/telegram/TelegramContext.ts
+++ b/packages/bottender/src/telegram/TelegramContext.ts
@@ -153,6 +153,22 @@ class TelegramContext extends Context<TelegramClient, TelegramEvent> {
     return this._client.answerInlineQuery(inlineQueryId, results, options);
   }
 
+  async answerCallbackQuery(
+    options: Type.AnswerCallbackQueryOption
+  ): Promise<boolean | null> {
+    if (!this._event.isCallbackQuery) {
+      warning(
+        false,
+        'answerCallbackQuery: should only be called to answer CallbackQuery event'
+      );
+      return null;
+    }
+
+    const callbackQueryId = (this._event.callbackQuery as any).id;
+
+    return this._client.answerCallbackQuery(callbackQueryId, options);
+  }
+
   async getUserProfilePhotos(
     options?: Type.GetUserProfilePhotosOption
   ): Promise<Type.UserProfilePhotos | null> {


Test patch:
diff --git a/packages/bottender/src/telegram/__tests__/TelegramContext.spec.ts b/packages/bottender/src/telegram/__tests__/TelegramContext.spec.ts
index ad5f87ce..39ef6ca5 100644
--- a/packages/bottender/src/telegram/__tests__/TelegramContext.spec.ts
+++ b/packages/bottender/src/telegram/__tests__/TelegramContext.spec.ts
@@ -848,6 +848,100 @@ describe('#answerInlineQuery', () => {
   });
 });
 
+describe('#answerCallbackQuery', () => {
+  const callbackQuery = {
+    updateId: 869424,
+    callbackQuery: {
+      id: '705303069014561',
+      from: {
+        id: 164230,
+        isBot: false,
+        firstName: 'user_first',
+        username: 'username',
+        languageCode: 'zh-hans',
+      },
+      message: {
+        messageId: 1474,
+        from: {
+          id: 902548,
+          isBot: true,
+          firstName: 'bot_first',
+          username: 'botname',
+        },
+        chat: {
+          id: -371089,
+          title: 'group name',
+          type: 'group',
+          allMembersAreAdministrators: true,
+        },
+        date: 1588145587,
+        game: {
+          title: 'game title',
+          description: 'game description',
+          photo: [
+            {
+              fileId:
+                'AgACAgUAAxUAAV6pNvEYJWk8Nn7D-P9i8KxCkeBJAAL5qjEbZ5BIVdV5MmS2G44AAfN1w2p0AAMBAAMCAANtAANXSw',
+              fileUniqueId: 'AQAD83XDanQAA1',
+              fileSize: 8889,
+              width: 320,
+              height: 180,
+            },
+            {
+              fileId:
+                'AgACAgUAAxUAAV6pNvEYJWk8Nn7D-P9i8KxCkeBJAAL5qjEbZ5BIVdV5MmS2G44AAfN1w2p0AAMBAAMCAAN4AANYSw',
+              fileUniqueId: 'AQAD83XDanQAA1',
+              fileSize: 20067,
+              width: 640,
+              height: 360,
+            },
+          ],
+        },
+        replyMarkup: {
+          inlineKeyboard: [
+            [
+              {
+                text: 'Play gamename',
+                callbackGame: {},
+              },
+            ],
+          ],
+        },
+      },
+      chatInstance: '-811839530613755',
+      gameShortName: 'gamename',
+    },
+  };
+  it('should to call client.answerCallbackQuery', async () => {
+    const { context, client } = setup({ rawEvent: callbackQuery });
+
+    const response = {
+      ok: true,
+    };
+
+    client.answerCallbackQuery.mockResolvedValue(response);
+
+    const result = await context.answerCallbackQuery({
+      url: 'https://example.com/',
+    });
+
+    expect(client.answerCallbackQuery).toBeCalledWith('705303069014561', {
+      url: 'https://example.com/',
+    });
+    expect(result).toEqual(response);
+  });
+
+  it('should not call answerCallbackQuery method if event type is not CallbackQuery', async () => {
+    const { context, client } = setup();
+
+    await context.answerCallbackQuery({
+      url: 'https://example.com/',
+    });
+
+    expect(client.answerCallbackQuery).not.toBeCalled();
+  });
+});
+
 describe('#getUserProfilePhotos', () => {
   it('should to call client.getUserProfilePhotos', async () => {
     const { context, client } = setup();