Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .claude/skills/documentation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ The Glific frontend lives at `../glific-frontend/` relative to this repo.
| `../glific-frontend/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx` | All route paths (maps feature name → URL) |
| `../glific-frontend/src/graphql/queries/` | GraphQL queries (understand data a feature displays) |

### Backend code location

The Glific backend (Elixir/Phoenix, repo `glific/glific`) lives at `../glific/` relative to this repo. Read it only to confirm **user-observable behavior** the frontend doesn't make obvious — defaults, validation rules, limits, what a setting actually does, why an action is blocked. Do **not** document internal architecture (see the anti-patterns in `style-writing.md`).

| Path | What it contains |
|------|-----------------|
| `../glific/lib/glific/{feature}/` | Domain logic for a feature — defaults, validations, business rules |
| `../glific/lib/glific/{feature}.ex` | The feature's public context module (entry-point functions) |
| `../glific/lib/glific_web/resolvers/{feature}.ex` | GraphQL resolvers — what each query/mutation actually does |
| `../glific/lib/glific_web/schema/{feature}_types.ex` | GraphQL types, fields, and args exposed for the feature |

## File index

| File | Purpose |
Expand Down
2 changes: 2 additions & 0 deletions .claude/skills/documentation/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ Read what's needed for the task:
3. Read `../glific-frontend/src/routes/AuthenticatedRoute/AuthenticatedRoute.tsx` to find the URL route
4. Check existing docs in `docs/` for the feature (search for the feature name in file names and content)
5. Optionally read `../glific-frontend/src/graphql/queries/{Feature}.ts` to understand what data the feature displays
6. If user-observable behavior is unclear from the UI alone (defaults, validation rules, limits, why an action is blocked/allowed), read the backend: `../glific/lib/glific/{feature}/` and `../glific/lib/glific/{feature}.ex` for domain logic, `../glific/lib/glific_web/resolvers/{feature}.ex` and `../glific/lib/glific_web/schema/{feature}_types.ex` for what each query/mutation exposes. Translate findings into plain user-facing language — never document internal architecture.

**Mode B — PR Number:**
1. `gh pr diff #PR_NUMBER --repo glific/glific-frontend` to see what changed
2. Identify affected containers from the changed file paths
3. Read the changed files in full to understand new behavior
4. Check existing docs for the affected area
5. If the PR is in the backend repo (`glific/glific`) or the frontend change depends on backend behavior, run `gh pr diff #PR_NUMBER --repo glific/glific` and/or read the relevant `../glific/lib/...` files (see the backend paths above) to understand the user-observable change

## 4. Determine Placement

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@

<h3>
<table>
<tr>
<td><b>3 minutes read</b></td>
<td style={{ paddingLeft: '40px' }}><b>Level: Advanced </b></td>
<td style={{ paddingLeft: '40px' }}><b>Last Updated: March 2026</b></td>
<td style={{ paddingLeft: '40px' }}><b>Last Updated: June 2026</b></td>
</tr>
</table>
</h3>

**Webhook calls are used to communicate with third-party applications within flows. They allow NGOs to receive and handle incoming messages, delivery receipts and other events from WhatsApp in a seamless and automated manner.**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Clarify the webhook description.

The current description conflates Glific's role as a WhatsApp Business API client (receiving incoming messages and delivery receipts) with the flow action "Call a webhook," which makes outbound HTTP requests from a flow to external APIs. This could confuse readers about what the webhook flow action actually does.

Consider rephrasing to focus on outbound calls to external APIs, e.g.:

Webhook calls let flows send data to external APIs and use the response in subsequent steps.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/4`. Product Features/03. Flows/2. Flow Actions/11. Call a webhook.md at
line 11, The current webhook description in the flow action docs mixes inbound
WhatsApp handling with the outbound behavior of Call a webhook. Update the
description in the webhook flow action documentation to clearly state that this
action sends data from a flow to an external API and can use the response in
later steps, using the “Call a webhook” terminology to avoid confusion with
WhatsApp message reception.


___
---

## Using Webhooks in Glific

Please have a look at the steps to call Webhooks in Glific.
Expand All @@ -21,11 +21,11 @@ Please have a look at the steps to call Webhooks in Glific.
![image](https://user-images.githubusercontent.com/32592458/212661318-ed2b2fa8-2f4a-4b6b-a2f3-7c00b8aa36d2.png)

2. Call Webhook in a node.
1. Choose to `Call a webhook` in the dropdown in node action.
1. Choose `POST` in response type.
1. Enter the `URL` where you want a Webhook connection.
1. Click on the `Post Body` tab.
1. Enter the variables which you want to pass through the webhook.
1. Choose to `Call a webhook` in the dropdown in node action.
1. Choose `POST` in response type.
1. Enter the `URL` where you want a Webhook connection.
1. Click on the `Post Body` tab.
1. Enter the variables which you want to pass through the webhook.
Comment on lines +24 to +28

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use precise terminology for the HTTP method dropdown.

Line 25 says "Choose POST in response type" but the dropdown selects the HTTP method (GET/POST), not a "response type." Update to:

  1. Choose POST as the HTTP method.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/4`. Product Features/03. Flows/2. Flow Actions/11. Call a webhook.md
around lines 24 - 28, The “Call a webhook” flow text uses the wrong term for the
dropdown selection; update the step in the webhook docs to refer to the HTTP
method instead of “response type.” In the “Call a webhook” section, revise the
instruction around the POST selection so it clearly says to choose POST as the
HTTP method, matching the dropdown behavior and terminology used elsewhere in
the flow actions docs.


```
{
Expand All @@ -38,22 +38,18 @@ Please have a look at the steps to call Webhooks in Glific.

![image](https://user-images.githubusercontent.com/32592458/212661350-bf2ce325-4fbf-4882-b947-10f7eb660f3f.png)



![image](https://user-images.githubusercontent.com/32592458/212661387-ebb6e6c4-b675-4a26-ada3-d816f39c1f70.png)

3. Click `OK` to save the changes

---

___
# Use webhook response in the flows

1. Let&#39;s say you make a webhook call (by using the above steps) and you want to use the response variable in the flow.
1. Let&#39;s say you make a webhook call (by using the above steps) and you want to use the response variable in the flow.
Comment on lines 47 to +49

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fix awkward heading and repetitive phrasing.

  • Line 47: "Use webhook response in the flows" → "Use webhook response in flows" or "Using webhook responses in flows"
  • Line 49: Static analysis flagged repetitive "you... and you want to" phrasing. Rephrase for clarity, e.g.:

After making a webhook call with the steps above, you can use the response variables in the flow.

🧰 Tools
🪛 LanguageTool

[style] ~49-~49: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...call (by using the above steps) and you want to use the response variable in the flow. ...

(REP_WANT_TO_VB)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/4`. Product Features/03. Flows/2. Flow Actions/11. Call a webhook.md
around lines 47 - 49, The heading and example sentence in the webhook flow docs
are awkward and repetitive; update the section title near the “Use webhook
response” text to read naturally without “the” before “flows,” and rephrase the
sentence in the “Call a webhook” content to remove the “you... and you want to”
wording. Use the existing webhook-response section text as the target and keep
the meaning while making it concise and clear.

Source: Linters/SAST tools


![image](https://user-images.githubusercontent.com/32592458/212661423-cdbd967e-d435-48b3-982f-fe59cf08f51a.png)



For example, if you send a response like a below object

```
Expand All @@ -63,17 +59,71 @@ For example, if you send a response like a below object
}
```

> Please note that your webhook should always return a JSON object (not an array).
> Your webhook should return JSON. A JSON object is the simplest to work with, but arrays are also supported — see [How the response should be structured](#how-the-response-should-be-structured) below.

Then you can use that response as **@results.mywebhook.success_message** Or if you want to use any other variable then it will be **@results.mywebhook.*YOUR_RESPONSE_OBJECT_KEY**
Then you can use that response as **@results.mywebhook.success_message** Or if you want to use any other variable then it will be **@results.mywebhook.\*YOUR_RESPONSE_OBJECT_KEY**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Escape or rephrase the wildcard placeholder.

The *YOUR_RESPONSE_OBJECT_KEY* uses asterisks that Markdown renders as italics, making the placeholder appear as @results.mywebhook.YOUR_RESPONSE_OBJECT_KEY without any visible wildcard marker. Readers may not realize * was intended as a meta-symbol. Use backticks or a different convention:

@results.mywebhook.<YOUR_RESPONSE_OBJECT_KEY>

or escape the asterisks: \*YOUR_RESPONSE_OBJECT_KEY\*

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/4`. Product Features/03. Flows/2. Flow Actions/11. Call a webhook.md at
line 64, The webhook docs example in the “Call a webhook” flow action uses a
Markdown-emphasized wildcard placeholder that renders incorrectly. Update the
text around the `@results.mywebhook.*YOUR_RESPONSE_OBJECT_KEY*` example to avoid
italic formatting by either wrapping the placeholder in backticks or rephrasing
it with angle brackets, so the `*` is preserved as an intentional meta-symbol
when readers view the rendered documentation.


![image](https://user-images.githubusercontent.com/32592458/212661557-e5e73775-1c71-4ea9-b2f2-81cf809db3ba.png)

Here my webhook is a custom name you defined on your webhook node and **success_message** is the key of the response object you send back in a webhook call.

## How the response should be structured

Here my webhook is a custom name you defined on your webhook node and **success_message** is the key of the response object you send back in a webhook call.
When your external API replies to a webhook call, Glific reads the **JSON body** of the response and saves it under your webhook's result name. A few rules decide what you can read back:

- **Return JSON.** Glific only parses JSON response bodies. If the body is not valid JSON, nothing is saved to the result and the call is logged as an error.
- **A JSON object is the cleanest choice.** Every key in the object becomes a value you can read with **@results.YOUR_WEBHOOK_NAME.KEY**.
- **Arrays are supported too.** If your API returns a JSON array, Glific turns it into numbered keys starting at `0` — the first item is `0`, the second is `1`, and so on. You then read an item by its number.
- **Nesting is limited to 5 parts in a path.** Glific keeps the full shape of your JSON — objects inside objects, arrays inside objects — but it can only read a path that is up to **five dot-separated parts** long. Counting `@results` and your webhook name, that leaves room to go **3 levels deep inside your response** (for example `@results.mywebhook.user.address.city`). Anything deeper is not read, so keep the values you need within that depth.

Comment on lines +70 to +78

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Clarify what "nothing is saved" means for flow authors.

Line 80 states that invalid JSON means "nothing is saved to the result and the call is logged as an error." Consider clarifying whether the flow can still continue (with an empty result) or if the webhook node itself errors and stops flow execution. This distinction matters for authors designing error-handling paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/4`. Product Features/03. Flows/2. Flow Actions/11. Call a webhook.md
around lines 76 - 84, Clarify the invalid-JSON behavior in the webhook response
section so flow authors know what happens after a parse failure. Update the “How
the response should be structured” guidance to state whether the webhook step in
the Call a webhook flow action still completes with an empty result or instead
errors/stops execution, and make that behavior explicit near the JSON parsing
rules in this document.

## Accessing nested values

You reach a value by writing its path after the webhook name, separating each level with a dot:

**@results.YOUR_WEBHOOK_NAME.LEVEL1.LEVEL2...**

Say your webhook is named **mywebhook** and your API returns this:

```json
{
"status": "success",
"user": {
"name": "Anita",
"address": {
"city": "Mumbai",
"pincode": "400001"
}
},
"courses": [
{ "title": "Maths", "score": 88 },
{ "title": "Science", "score": 92 }
]
}
```

Here is how to read each value:

| You want | Use this |
| ----------------------------------------- | -------------------------------------- |
| The status | `@results.mywebhook.status` |
| The user's name | `@results.mywebhook.user.name` |
| The user's city (object inside an object) | `@results.mywebhook.user.address.city` |
| The first course title (array → item `0`) | `@results.mywebhook.courses.0.title` |
| The second course's score | `@results.mywebhook.courses.1.score` |

A few things to keep in mind:

- **A path can be at most 5 parts long.** `@results.mywebhook.user.address.city` is the deepest you can read (that is 3 levels into your response). A value buried deeper — `@results.mywebhook.a.b.c.d` — will not be read. If your data is deeper than that, flatten it in your API before returning it.
- **Array items are numbered from `0`.** The first item is always `0`, not `1`.
- **Match the keys exactly**, including upper- and lower-case. `@results.mywebhook.User.name` will not find `user`.
- **Check a value exists before you use it.** If a key is missing from the response, its path returns nothing. Use a **Wait for result** or a split node to branch on whether the value came back.

Comment on lines +117 to +120

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify exact node type names in Glific documentation or codebase
rg -n "Wait for result" docs/
rg -n "split node" docs/
rg -n "Split by" docs/ --type md

Repository: glific/docs

Length of output: 9250


Update the specific node name for handling missing values.

While "Wait for result" is the correct node name, "split node" is too generic and does not match the Glific UI. The precise node for branching based on workflow results is Split by a result in the flow.

Replace "split node" with "Split by a result in the flow" in the guidance:

Use a Wait for result or a Split by a result in the flow node to branch on whether the value came back.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/4`. Product Features/03. Flows/2. Flow Actions/11. Call a webhook.md
around lines 122 - 125, The guidance for handling missing values uses the wrong
node name, so update the prose in the webhook flow docs to reference the exact
Glific UI label. In the section discussing checking whether a value exists
before use, replace the generic “split node” wording with “Split by a result in
the flow” and keep “Wait for result” unchanged so the branching instruction
matches the actual workflow node names.

:::note
Want to confirm the exact shape your API returned? Open **Webhook Logs** (below) and view the **Response JSON** for that call. Copy the key names straight from there to build your paths.
:::
Comment thread
coderabbitai[bot] marked this conversation as resolved.

---

___
## Checking Webhook Logs

Once the webhook setup is complete. You can test it by executing the flow in Glific. There may a case, the webhook is not set up correctly and there are some errors in Webhook calls.
Expand All @@ -84,17 +134,16 @@ Glific has **Webhook Logs** from where you can check the status of a Webhook cal

<img width="221" alt="Screenshot 2024-03-06 at 3 13 42 PM" src="https://github.com/glific/docs/assets/141305477/179b8f35-1f72-499b-8271-9488d0eedbac" />


1. Webhook logs page will show the results of your webhook calls with the below details
1. `Time` - Time of the webhook call.
1. `URL` - The URL which is used in webhook call.
1. `Status` - Success / Error
1. `Status Code`- Status code returned from the webhook call.
1. `Error` - Error is an error returned. NULL in the case of success
1. `Method` - GET / POST
1. `Request Header` - Request header of the webhook call
1. `Request JSON` - JSON of the webhook call
1. `Response JSON` - JSON response received from the webhook call.
1. `Time` - Time of the webhook call.
1. `URL` - The URL which is used in webhook call.
1. `Status` - Success / Error
1. `Status Code`- Status code returned from the webhook call.
1. `Error` - Error is an error returned. NULL in the case of success
1. `Method` - GET / POST
1. `Request Header` - Request header of the webhook call
1. `Request JSON` - JSON of the webhook call
1. `Response JSON` - JSON response received from the webhook call.
Comment on lines 137 to +146

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Fix formatting and awkward phrasing in the log fields list.

  • Line 142: `Status Code`- → add space: `Status Code` -
  • Line 143: "Error is an error returned. NULL in the case of success" → rephrase to "Error message, or NULL if the call succeeded."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/4`. Product Features/03. Flows/2. Flow Actions/11. Call a webhook.md
around lines 137 - 146, The webhook logs field list has inconsistent formatting
and awkward wording in the “Status Code” and “Error” entries. Update the
“Webhook logs page” list in the Call a webhook documentation so the “Status
Code” label uses proper spacing before the dash, and rephrase the “Error”
description to a clearer, concise sentence such as indicating it is the error
message or NULL on success.


<img width="1451" alt="Screenshot 2024-03-06 at 3 12 51 PM" src="https://github.com/glific/docs/assets/141305477/d7f9dffe-2294-42e3-9b93-8bc3bfa38c38" />

Expand All @@ -105,7 +154,8 @@ Glific has **Webhook Logs** from where you can check the status of a Webhook cal
1. `View` will open up the response received in a pop-up window. You can check or copy the text to know more details of the response.

![image](https://user-images.githubusercontent.com/32592458/212661806-2bdf38df-5791-492e-9c4f-a6c3fc7e919b.png)
___

---

## Reference Article

Expand Down
Loading