Repository: Yoctol/bottender
Pull request #672 (2020-03-04 07:03:45)

feat(whatsapp): construct client with phoneNumber
Add `phoneNumber` config to the constructor.

codecov-io: # [Codecov](https://codecov.io/gh/Yoctol/bottender/pull/672?src=pr&el=h1) Report
> Merging [#672](https://codecov.io/gh/Yoctol/bottender/pull/672?src=pr&el=desc) into [release/1.3](https://codecov.io/gh/Yoctol/bottender/commit/8ae28a91930cb8e3ebedbf6eafad2d69dd0ab1fa?src=pr&el=desc) will **increase** coverage by `0.01%`.
> The diff coverage is `100%`.

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

```diff
@@               Coverage Diff               @@
##           release/1.3     #672      +/-   ##
===============================================
+ Coverage         80.9%   80.91%   +0.01%     
===============================================
  Files              108      108              
  Lines             4482     4481       -1     
  Branches          1109     1119      +10     
===============================================
  Hits              3626     3626              
+ Misses             809      804       -5     
- Partials            47       51       +4
```


| [Impacted Files](https://codecov.io/gh/Yoctol/bottender/pull/672?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [packages/bottender/src/whatsapp/WhatsappBot.ts](https://codecov.io/gh/Yoctol/bottender/pull/672/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy93aGF0c2FwcC9XaGF0c2FwcEJvdC50cw==) | `100% <ø> (ø)` | :arrow_up: |
| [...s/create-bottender-app/src/utils/generateConfig.ts](https://codecov.io/gh/Yoctol/bottender/pull/672/diff?src=pr&el=tree#diff-cGFja2FnZXMvY3JlYXRlLWJvdHRlbmRlci1hcHAvc3JjL3V0aWxzL2dlbmVyYXRlQ29uZmlnLnRz) | `0% <ø> (ø)` | :arrow_up: |
| [packages/bottender/src/whatsapp/WhatsappContext.ts](https://codecov.io/gh/Yoctol/bottender/pull/672/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy93aGF0c2FwcC9XaGF0c2FwcENvbnRleHQudHM=) | `83.33% <ø> (+8.33%)` | :arrow_up: |
| [packages/bottender/src/whatsapp/TwilioClient.ts](https://codecov.io/gh/Yoctol/bottender/pull/672/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy93aGF0c2FwcC9Ud2lsaW9DbGllbnQudHM=) | `58.33% <100%> (+1.81%)` | :arrow_up: |
| [...ckages/bottender/src/whatsapp/WhatsappConnector.ts](https://codecov.io/gh/Yoctol/bottender/pull/672/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy93aGF0c2FwcC9XaGF0c2FwcENvbm5lY3Rvci50cw==) | `90.62% <100%> (ø)` | :arrow_up: |
| [packages/bottender/src/getClient.ts](https://codecov.io/gh/Yoctol/bottender/pull/672/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy9nZXRDbGllbnQudHM=) | `55.55% <0%> (ø)` | :arrow_up: |
| [packages/create-bottender-app/src/shared/log.ts](https://codecov.io/gh/Yoctol/bottender/pull/672/diff?src=pr&el=tree#diff-cGFja2FnZXMvY3JlYXRlLWJvdHRlbmRlci1hcHAvc3JjL3NoYXJlZC9sb2cudHM=) | `0% <0%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Yoctol/bottender/pull/672?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/672?src=pr&el=footer). Last update [8ae28a9...a814e1d](https://codecov.io/gh/Yoctol/bottender/pull/672?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/packages/bottender/src/whatsapp/TwilioClient.ts b/packages/bottender/src/whatsapp/TwilioClient.ts
index 251fc1c7..dc7fe346 100644
--- a/packages/bottender/src/whatsapp/TwilioClient.ts
+++ b/packages/bottender/src/whatsapp/TwilioClient.ts
@@ -13,6 +13,7 @@ import {
 type ClientConfig = {
   accountSid: string;
   authToken: string;
+  phoneNumber: string;
   origin?: string;
 };
 
@@ -36,10 +37,13 @@ export default class TwilioClient {
 
   _authToken: string;
 
+  _phoneNumber: string;
+
   constructor(config: ClientConfig) {
     const twilioOrigin = `https://${config.accountSid}:${config.authToken}@api.twilio.com`;
 
     this._authToken = config.authToken;
+    this._phoneNumber = config.phoneNumber;
 
     this._axios = axios.create({
       baseURL: `${config.origin || twilioOrigin}/2010-04-01/Accounts/${
@@ -66,7 +70,7 @@ export default class TwilioClient {
   }
 
   async createMessage(message: {
-    from: string;
+    from?: string;
     body: string;
     to: string;
     maxPrice?: number;
@@ -101,7 +105,15 @@ export default class TwilioClient {
         subresource_uris: {
           uri: string;
         };
-      }>('/Messages.json', qs.stringify(pascalcaseKeys(message)));
+      }>(
+        '/Messages.json',
+        qs.stringify(
+          pascalcaseKeys({
+            from: this._phoneNumber,
+            ...message,
+          })
+        )
+      );
       return camelcaseKeys(data);
     } catch (err) {
       handleError(err);
diff --git a/packages/bottender/src/whatsapp/WhatsappBot.ts b/packages/bottender/src/whatsapp/WhatsappBot.ts
index 3ae572c0..a695e567 100644
--- a/packages/bottender/src/whatsapp/WhatsappBot.ts
+++ b/packages/bottender/src/whatsapp/WhatsappBot.ts
@@ -13,12 +13,14 @@ export default class WhatsappBot extends Bot<
   constructor({
     accountSid,
     authToken,
+    phoneNumber,
     sessionStore,
     sync,
     origin,
   }: {
     accountSid: string;
     authToken: string;
+    phoneNumber: string;
     sessionStore?: SessionStore;
     sync?: boolean;
     origin?: string;
@@ -26,6 +28,7 @@ export default class WhatsappBot extends Bot<
     const connector = new WhatsappConnector({
       accountSid,
       authToken,
+      phoneNumber,
       origin,
     });
     super({ connector, sessionStore, sync });
diff --git a/packages/bottender/src/whatsapp/WhatsappConnector.ts b/packages/bottender/src/whatsapp/WhatsappConnector.ts
index 5f248394..0df4fdfa 100644
--- a/packages/bottender/src/whatsapp/WhatsappConnector.ts
+++ b/packages/bottender/src/whatsapp/WhatsappConnector.ts
@@ -14,6 +14,7 @@ export type WhatsappRequestBody = any;
 type ConstructorOptionsWithoutClient = {
   accountSid: string;
   authToken: string;
+  phoneNumber: string;
   origin?: string;
 };
 
@@ -49,11 +50,12 @@ export default class WhatsappConnector
     if ('client' in options) {
       this._client = options.client;
     } else {
-      const { accountSid, authToken, origin } = options;
+      const { accountSid, authToken, phoneNumber, origin } = options;
 
       this._client = TwilioClient.connect({
         accountSid,
         authToken,
+        phoneNumber,
         origin,
       });
     }
diff --git a/packages/bottender/src/whatsapp/WhatsappContext.ts b/packages/bottender/src/whatsapp/WhatsappContext.ts
index 51f03b74..6c677b51 100644
--- a/packages/bottender/src/whatsapp/WhatsappContext.ts
+++ b/packages/bottender/src/whatsapp/WhatsappContext.ts
@@ -28,17 +28,12 @@ class WhatsappContext extends Context<TwilioClient, WhatsappEvent> {
       mediaUrl?: string[];
     }
   ): Promise<any> {
-    const from =
-      this._event.rawEvent.smsStatus === 'received'
-        ? this._event.rawEvent.to
-        : this._event.rawEvent.from;
     const to =
       this._event.rawEvent.smsStatus === 'received'
         ? this._event.rawEvent.from
         : this._event.rawEvent.to;
 
     return this._client.createMessage({
-      from,
       to,
       body: text,
       ...options,
diff --git a/packages/create-bottender-app/src/utils/generateConfig.ts b/packages/create-bottender-app/src/utils/generateConfig.ts
index 84a27ded..27708944 100644
--- a/packages/create-bottender-app/src/utils/generateConfig.ts
+++ b/packages/create-bottender-app/src/utils/generateConfig.ts
@@ -42,6 +42,7 @@ const generateConfig = (session: Session, platforms: Platform[]): string =>
       path: '/webhooks/whatsapp',
       accountSid: process.env.WHATSAPP_ACCOUNT_SID,
       authToken: process.env.WHATSAPP_AUTH_TOKEN,
+      phoneNumber: process.env.WHATSAPP_PHONE_NUMBER,
     },
     line: {
       enabled: ${platforms.includes('line')},
diff --git a/packages/create-bottender-app/template-typescript/.env.example b/packages/create-bottender-app/template-typescript/.env.example
index a670ac45..cc4424af 100644
--- a/packages/create-bottender-app/template-typescript/.env.example
+++ b/packages/create-bottender-app/template-typescript/.env.example
@@ -6,6 +6,7 @@ MESSENGER_VERIFY_TOKEN=
 
 WHATSAPP_ACCOUNT_SID=
 WHATSAPP_AUTH_TOKEN=
+WHATSAPP_PHONE_NUMBER=
 
 LINE_ACCESS_TOKEN=
 LINE_CHANNEL_SECRET=
diff --git a/packages/create-bottender-app/template/.env.example b/packages/create-bottender-app/template/.env.example
index 8876dbe0..a149b915 100644
--- a/packages/create-bottender-app/template/.env.example
+++ b/packages/create-bottender-app/template/.env.example
@@ -6,6 +6,7 @@ MESSENGER_VERIFY_TOKEN=
 
 WHATSAPP_ACCOUNT_SID=
 WHATSAPP_AUTH_TOKEN=
+WHATSAPP_PHONE_NUMBER=
 
 LINE_ACCESS_TOKEN=
 LINE_CHANNEL_SECRET=


Test patch:
diff --git a/packages/bottender/src/whatsapp/__tests__/WhatsappContext.spec.ts b/packages/bottender/src/whatsapp/__tests__/WhatsappContext.spec.ts
index 1b3122c9..16b761fa 100644
--- a/packages/bottender/src/whatsapp/__tests__/WhatsappContext.spec.ts
+++ b/packages/bottender/src/whatsapp/__tests__/WhatsappContext.spec.ts
@@ -21,6 +21,7 @@ function setup() {
   const client = new TwilioClient({
     accountSid: 'ACCOUNT_SID',
     authToken: 'AUTH_TOKEN',
+    phoneNumber: 'whatsapp:+14155238886',
   });
 
   client.createMessage = jest.fn();
@@ -50,7 +51,6 @@ describe('#sendText', () => {
 
     expect(client.createMessage).toBeCalledWith({
       body: 'hi',
-      from: 'whatsapp:+14155238886',
       to: 'whatsapp:+886123456789',
     });
   });
@@ -70,7 +70,6 @@ describe('#sendText', () => {
 
     expect(client.createMessage).toBeCalledWith({
       body: 'hi',
-      from: 'whatsapp:+14155238886',
       to: 'whatsapp:+886123456789',
       maxPrice: 10,
       provideFeedback: true,