瀏覽代碼

feat(invite): add basic analytics for AddPeople dialog (#2641)

* feat(invite): add basic analytics for AddPeople dialog

Analytics for opening the dialog, closing the dialog, the
count of invites sent, and the count of invites errored.

* squash: fix typo, change default count init, remove extra analytics param
j8
virtuacoplenny 7 年之前
父節點
當前提交
83f47c2df1
共有 2 個檔案被更改,包括 78 行新增6 行删除
  1. 10
    5
      react/features/analytics/AnalyticsEvents.js
  2. 68
    1
      react/features/invite/components/AddPeopleDialog.web.js

+ 10
- 5
react/features/analytics/AnalyticsEvents.js 查看文件

129
 }
129
 }
130
 
130
 
131
 /**
131
 /**
132
- * Creates an event which indicates that the invite dialog was closed. This is
133
- * not a TYPE_UI event, since it is not necessarily the result of a user
134
- * interaction.
132
+ * Creates an event for an action regarding the AddPeopleDialog (invites).
135
  *
133
  *
134
+ * @param {string} action - The action that the event represents.
135
+ * @param {string} actionSubject - The subject that was acted upon.
136
+ * @param {boolean} attributes - Additional attributes to attach to the event.
136
  * @returns {Object} The event in a format suitable for sending via
137
  * @returns {Object} The event in a format suitable for sending via
137
  * sendAnalytics.
138
  * sendAnalytics.
138
  */
139
  */
139
-export function createInviteDialogClosedEvent() {
140
+export function createInviteDialogEvent(
141
+        action, actionSubject, attributes = {}) {
140
     return {
142
     return {
141
-        action: 'invite.dialog.closed'
143
+        action,
144
+        actionSubject,
145
+        attributes,
146
+        source: 'inviteDialog'
142
     };
147
     };
143
 }
148
 }
144
 
149
 

+ 68
- 1
react/features/invite/components/AddPeopleDialog.web.js 查看文件

6
 import React, { Component } from 'react';
6
 import React, { Component } from 'react';
7
 import { connect } from 'react-redux';
7
 import { connect } from 'react-redux';
8
 
8
 
9
+import { createInviteDialogEvent, sendAnalytics } from '../../analytics';
9
 import { getInviteURL } from '../../base/connection';
10
 import { getInviteURL } from '../../base/connection';
10
 import { Dialog, hideDialog } from '../../base/dialog';
11
 import { Dialog, hideDialog } from '../../base/dialog';
11
 import { translate } from '../../base/i18n';
12
 import { translate } from '../../base/i18n';
143
         };
144
         };
144
     }
145
     }
145
 
146
 
147
+    /**
148
+     * Sends an analytics event to record the dialog has been shown.
149
+     *
150
+     * @inheritdoc
151
+     * @returns {void}
152
+     */
153
+    componentDidMount() {
154
+        sendAnalytics(createInviteDialogEvent(
155
+            'invite.dialog.opened', 'dialog'));
156
+    }
157
+
146
     /**
158
     /**
147
      * React Component method that executes once component is updated.
159
      * React Component method that executes once component is updated.
148
      *
160
      *
162
         }
174
         }
163
     }
175
     }
164
 
176
 
177
+    /**
178
+     * Sends an analytics event to record the dialog has been closed.
179
+     *
180
+     * @inheritdoc
181
+     * @returns {void}
182
+     */
183
+    componentWillUnmount() {
184
+        sendAnalytics(createInviteDialogEvent(
185
+            'invite.dialog.closed', 'dialog'));
186
+    }
187
+
165
     /**
188
     /**
166
      * Renders the content of this component.
189
      * Renders the content of this component.
167
      *
190
      *
231
         return text.replace(/\D/g, '');
254
         return text.replace(/\D/g, '');
232
     }
255
     }
233
 
256
 
257
+    /**
258
+     * Helper for determining how many of each type of user is being invited.
259
+     * Used for logging and sending analytics related to invites.
260
+     *
261
+     * @param {Array} inviteItems - An array with the invite items, as created
262
+     * in {@link _parseQueryResults}.
263
+     * @private
264
+     * @returns {Object} An object with keys as user types and values as the
265
+     * number of invites for that type.
266
+     */
267
+    _getInviteTypeCounts(inviteItems = []) {
268
+        const inviteTypeCounts = {};
269
+
270
+        inviteItems.forEach(i => {
271
+            const type = i.item.type;
272
+
273
+            if (!inviteTypeCounts[type]) {
274
+                inviteTypeCounts[type] = 0;
275
+            }
276
+
277
+            inviteTypeCounts[type]++;
278
+        });
279
+
280
+        return inviteTypeCounts;
281
+    }
282
+
234
     _isAddDisabled: () => boolean;
283
     _isAddDisabled: () => boolean;
235
 
284
 
236
     /**
285
     /**
313
      * @returns {void}
362
      * @returns {void}
314
      */
363
      */
315
     _onSubmit() {
364
     _onSubmit() {
365
+        const inviteTypeCounts
366
+            = this._getInviteTypeCounts(this.state.inviteItems);
367
+
368
+        sendAnalytics(createInviteDialogEvent(
369
+            'clicked', 'inviteButton', {
370
+                ...inviteTypeCounts,
371
+                inviteAllowed: this._isAddDisabled()
372
+            }));
373
+
316
         if (this._isAddDisabled()) {
374
         if (this._isAddDisabled()) {
317
             return;
375
             return;
318
         }
376
         }
393
                 // If any invites are left that means something failed to send
451
                 // If any invites are left that means something failed to send
394
                 // so treat it as an error.
452
                 // so treat it as an error.
395
                 if (invitesLeftToSend.length) {
453
                 if (invitesLeftToSend.length) {
396
-                    logger.error(`${invitesLeftToSend.length} invites failed`);
454
+                    const erroredInviteTypeCounts
455
+                        = this._getInviteTypeCounts(invitesLeftToSend);
456
+
457
+                    logger.error(`${invitesLeftToSend.length} invites failed`,
458
+                        erroredInviteTypeCounts);
459
+
460
+                    sendAnalytics(createInviteDialogEvent(
461
+                        'error', 'invite', {
462
+                            ...erroredInviteTypeCounts
463
+                        }));
397
 
464
 
398
                     this.setState({
465
                     this.setState({
399
                         addToCallInProgress: false,
466
                         addToCallInProgress: false,

Loading…
取消
儲存