-
Notifications
You must be signed in to change notification settings - Fork 10
docs: Add Stats Table documentation to Reporting & Dashboard #629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
9a7d2ca
529e014
a47bd0b
842f208
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| # Understanding the Stats Table in Glific | ||
|
|
||
| The Stats table is Glific's built-in analytics system. It automatically records activity data for your organisation across different time windows so you can track how your bot is performing over time. | ||
|
|
||
| --- | ||
|
|
||
| ## Time Periods | ||
|
|
||
| Every stat record belongs to one of five time periods. The same metrics are calculated for each period independently. | ||
|
|
||
| | Period | What it covers | | ||
| |---|---| | ||
| | **Hour** | A single hour of activity | | ||
| | **Day** | A full calendar day (midnight to midnight) | | ||
| | **Week** | A full calendar week (Monday to Sunday) | | ||
| | **Month** | A full calendar month | | ||
| | **Summary** | A special snapshot generated at the end of each week and month — it covers the entire week or month in one calculation and is the most reliable figure to use for reporting | | ||
|
|
||
| > **Recommendation**: Always use the **Summary** period for reporting to stakeholders. It is calculated in a single pass and avoids the inconsistencies that can appear when comparing daily rows. | ||
|
Comment on lines
+7
to
+19
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial | 💤 Low value Consider briefly mentioning the The Stats Table schema includes For example: "Each stat record also includes a 🤖 Prompt for AI Agents |
||
|
|
||
| --- | ||
|
|
||
| ## Fields | ||
|
|
||
| ### `contacts` | ||
|
|
||
| **What it means**: The number of new contacts who were added to your organisation during this period. | ||
|
|
||
| **How it is calculated**: Counts contacts whose creation date falls within the time window. A contact who joined on December 3rd will appear in the December 3rd daily stat, the December weekly stat, and the December monthly stat. | ||
|
|
||
| **What to watch for**: This is a count of *new* additions only, not your total contact base. The Summary period is an exception — it returns your all-time total contact count. | ||
|
|
||
| --- | ||
|
|
||
| ### `active` | ||
|
|
||
| **What it means**: The number of contacts who sent a message to the bot during this period. | ||
|
|
||
| **How it is calculated**: Counts contacts whose "last messaged at" date falls within the time window. | ||
|
|
||
| **Important limitation**: A contact's "last messaged at" date is always updated to their most recent interaction. This means if a contact was active on December 1st but also sent a message on December 15th, they will no longer appear in the December 1st daily count. | ||
|
|
||
| --- | ||
|
|
||
| ### `optin` | ||
|
|
||
| **What it means**: Among the contacts who were active during this period, how many have opted in to receive messages from your organisation. | ||
|
|
||
| **How it is calculated**: Takes the set of active contacts for the period (same as the `active` count) and filters down to those who have an opt-in recorded at any point in the past. | ||
|
|
||
| **Critical clarification — this is not "who opted in this period"**: This field does not tell you how many people opted in during this specific time window. It tells you how many of the *currently active* contacts have ever opted in. If you want to know how many contacts opted in during a specific month, the contacts table needs to be queried directly. This is also the most likely reason for discrepancies if you have been cross-checking opt-in numbers. | ||
|
|
||
| --- | ||
|
|
||
| ### `optout` | ||
|
|
||
| **What it means**: Among the contacts who were active during this period, how many have opted out. | ||
|
|
||
| **How it is calculated**: Same approach as `optin` — takes the active contacts and filters to those who have an opt-out recorded at any point in the past. | ||
|
|
||
| **Same caveat as optin**: This is not "who opted out this period." It is the overlap between active contacts and contacts who have ever opted out. | ||
|
|
||
| --- | ||
|
|
||
| ### `messages` | ||
|
|
||
| **What it means**: The total number of messages sent and received during this period, across both directions. | ||
|
|
||
| **How it is calculated**: Counts all message records (inbound + outbound) created within the time window. | ||
|
|
||
| --- | ||
|
|
||
| ### `inbound` | ||
|
|
||
| **What it means**: The number of messages sent *to* the bot by contacts during this period. | ||
|
|
||
| **How it is calculated**: Counts only messages where the flow direction is inbound (contact → bot). | ||
|
|
||
| **Use case**: This is the closest proxy to genuine user engagement — a contact actively chose to send a message. | ||
|
|
||
| --- | ||
|
|
||
| ### `outbound` | ||
|
|
||
| **What it means**: The number of messages sent *from* the bot to contacts during this period. | ||
|
|
||
| **How it is calculated**: Counts only messages where the flow direction is outbound (bot → contact). | ||
|
|
||
| --- | ||
|
|
||
| ### `hsm` | ||
|
|
||
| **What it means**: The number of template messages sent during this period. HSM stands for Highly Structured Message, which is WhatsApp's term for pre-approved message templates. | ||
|
|
||
| **How it is calculated**: Counts outbound messages that are marked as HSM/template messages. | ||
|
|
||
| **Why this matters**: Template messages have a cost associated with them and are used to initiate conversations outside the 24-hour session window. Tracking this helps monitor your messaging costs. | ||
|
|
||
| --- | ||
|
|
||
| ### `flows_started` | ||
|
|
||
| **What it means**: The number of times a flow (automated conversation sequence) was triggered during this period. | ||
|
|
||
| **How it is calculated**: Counts flow sessions that were created within the time window. One contact going through a flow counts as one flow started, even if they send multiple messages within it. | ||
|
|
||
| --- | ||
|
|
||
| ### `flows_completed` | ||
|
|
||
| **What it means**: The number of flows that were completed (reached the end) during this period. | ||
|
|
||
| **How it is calculated**: Counts flow sessions whose completion timestamp falls within the time window. | ||
|
|
||
| **Use case**: Comparing `flows_started` to `flows_completed` gives you a drop-off rate — the percentage of contacts who started a flow but did not finish it. | ||
|
|
||
| --- | ||
|
|
||
| ### `users` | ||
|
|
||
| **What it means**: The number of Glific staff/agent users (not contacts) who logged in during this period. | ||
|
|
||
| **How it is calculated**: Counts Glific user accounts whose last login falls within the time window. For the Summary period, it returns the total number of user accounts registered. | ||
|
|
||
| **Note**: This tracks your organisation's internal team activity, not the contacts using your bot. | ||
|
|
||
| --- | ||
|
|
||
|
|
||
| ## Common Pitfalls | ||
|
|
||
| 1. **Do not use daily `active` counts for historical reporting.** They are revised downward as contacts continue to message after that date. Use monthly or summary figures instead. | ||
|
|
||
| 2. **The `optin` and `optout` columns are not cohort counts.** They do not tell you who opted in or out during that period. They tell you which active contacts have an opt-in or opt-out on record. | ||
|
|
||
| 3. **Weekly and daily figures may not add up perfectly.** Each is calculated independently, so small differences are expected. The Summary figure is always the authoritative number for a given period. | ||
|
|
||
| 4. **`messages` = `inbound` + `outbound` (approximately).** There may be a small difference due to system-generated messages, but these three fields should roughly balance. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Search for documentation about message counting logic
rg -n -C3 'messages.*inbound.*outbound|message.*count' --type=md -g '*BigQuery*'Repository: glific/docs Length of output: 37 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE='docs/4. Product Features/09. Reporting & Dashboard/09. Understanding the Stats Table.md'
echo '--- target file: show lines 120-170 ---'
sed -n '120,170p' "$FILE" | nl -ba | sed -e 's/^/LINE /'
echo '--- repo search for field definitions/wording ---'
rg -n --hidden --no-ignore-vcs \
'(Total messages|Messages received from contacts|Messages sent to contacts|system-generated|inbound|outbound|messages\s*=\s*inbound|messages.*inbound.*outbound)' \
--type=md docsRepository: glific/docs Length of output: 156 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE='docs/4. Product Features/09. Reporting & Dashboard/09. Understanding the Stats Table.md'
echo '--- target file: show lines 120-170 (with line numbers via awk) ---'
sed -n '120,170p' "$FILE" | awk '{printf "LINE %d: %s\n", NR+119, $0}'
echo '--- repo search for field definitions/wording ---'
rg -n --hidden --no-ignore-vcs \
'(Total messages|Messages received from contacts|Messages sent to contacts|system-generated|inbound|outbound|messages\s*=\s*inbound|messages.*inbound.*outbound)' \
--type=md docsRepository: glific/docs Length of output: 4631 🏁 Script executed: #!/bin/bash
set -euo pipefail
DOC1='docs/4. Product Features/09. Reporting & Dashboard/09. Understanding the Stats Table.md'
DOC2='docs/8. FAQ/Glific BigQuery Tables Guide.md'
echo '--- target file: show lines 50-110 ---'
sed -n '50,110p' "$DOC1" | awk '{print NR+49 ":" $0}'
echo '--- target file: show around Common Pitfalls line 139-150 ---'
sed -n '135,155p' "$DOC1" | awk '{print NR+134 ":" $0}'
echo '--- BigQuery guide: show around messages/inbound/outbound definitions (510-560) ---'
sed -n '510,560p' "$DOC2" | awk '{print NR+509 ":" $0}'
echo '--- search docs for "system-generated" ---'
rg -n --hidden --no-ignore-vcs 'system-generated' --type=md docsRepository: glific/docs Length of output: 6310 🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n --hidden --no-ignore-vcs \
'(system[- ]generated|system message|generated message|other direction|flow direction.*null|inbound \+ outbound|inbound.*outbound.*balance|roughly balance|messages.*inbound.*outbound)' \
--type=md docsRepository: glific/docs Length of output: 517 Align In 🤖 Prompt for AI Agents |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: glific/docs
Length of output: 885
🏁 Script executed:
Repository: glific/docs
Length of output: 133
🏁 Script executed:
Repository: glific/docs
Length of output: 6600
🏁 Script executed:
Repository: glific/docs
Length of output: 1793
Clarify “Summary” period wording to match the
period=summaryschemaThe line-17 text (“generated at the end of each week and month…covers the entire week or month”) reads like Summary represents two different aggregation types. Upstream schema defines
periodwith a single valuesummary= “overall totals”, and this doc’s field definitions also treat Summary as all-time totals (e.g.,contactsSummary returns your all-time total;usersSummary returns total user accounts registered). Reword line 17 to explicitly sayperiod=summaryis overall/all-time totals, and only mention weekly/monthly timing if you clarify it’s when the all-time totals snapshot is refreshed (e.g., via thedatefield).🤖 Prompt for AI Agents