Skip to content

Commit b15db4b

Browse files
committed
Add DevRev webhooks demo
1 parent de95801 commit b15db4b

File tree

4 files changed

+433
-0
lines changed

4 files changed

+433
-0
lines changed

webhooks/README.md

Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
# DevRev Webhooks Test Server (Go)
2+
3+
This is a simple Go server to test DevRev webhooks. It handles webhook
4+
verification and processes webhook events for work created, updated, and
5+
deleted.
6+
Detailed documentation on webhooks can be found [here](https://developer.devrev.ai/public/guides/webhooks).
7+
8+
## Setup
9+
10+
1. Start ngrok:
11+
```bash
12+
ngrok http 3000
13+
```
14+
15+
2. Register your webhook with DevRev using the ngrok URL:
16+
```bash
17+
curl --request POST 'https://api.devrev.ai/webhooks.create' \
18+
--header "Authorization: Bearer $DEVREV_TOKEN" \
19+
--header 'Content-Type: application/json' \
20+
--data-raw '{
21+
"event_types": [
22+
"work_created",
23+
"work_updated",
24+
"work_deleted"
25+
],
26+
"url": "your-ngrok-url"
27+
}'
28+
```
29+
30+
3. Start the webhook server:
31+
32+
The `WEBHOOK_SECRET` environment variable is required. It will be available as
33+
`secret` in the response of the above `webhooks.create` API call.
34+
35+
```bash
36+
WEBHOOK_SECRET=your_webhook_secret_here go run main.go
37+
```
38+
39+
## Example webhook payload
40+
41+
The following is an example of a `work_updated` webhook payload. Note that
42+
`work_updated` contains `old_work` and `work` fields.
43+
44+
```
45+
{
46+
"id": "don:integration:dvrv-us-1:devo/11FVC3ScK:webhook/1jGzMh1N:webhook_event/U7gbBDxjiWM",
47+
"timestamp": "2025-07-02T13:07:40.937074Z",
48+
"webhook_id": "don:integration:dvrv-us-1:devo/11FVC3ScK:webhook/1jGzMh1N",
49+
"work_updated": {
50+
"old_work": {
51+
"type": "issue",
52+
"applies_to_part": {
53+
"type": "product",
54+
"display_id": "PROD-2",
55+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:product/2",
56+
"id_v1": "don:DEV-11FVC3ScK:product:2",
57+
"name": "prod-foo",
58+
"owned_by": [
59+
{
60+
"type": "dev_user",
61+
"display_handle": "shivansh-rai",
62+
"display_id": "DEVU-1",
63+
"display_name": "shivansh-rai",
64+
"email": "[email protected]",
65+
"full_name": "Shivansh Rai",
66+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/1",
67+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-1",
68+
"state": "active",
69+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Shivansh%20Rai.png"
70+
}
71+
],
72+
"stage": {
73+
"name": ""
74+
}
75+
},
76+
"body": "\u003cdon:core:dvrv-us-1:devo/11FVC3ScK:issue/98\u003e",
77+
"created_by": {
78+
"type": "dev_user",
79+
"display_handle": "shivansh-rai",
80+
"display_id": "DEVU-1",
81+
"display_name": "shivansh-rai",
82+
"email": "[email protected]",
83+
"full_name": "Shivansh Rai",
84+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/1",
85+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-1",
86+
"state": "active",
87+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Shivansh%20Rai.png"
88+
},
89+
"created_date": "2025-06-14T13:20:46.963Z",
90+
"custom_fields": {
91+
"ctype__color": "Blue",
92+
"tnt__a_rich_text_field": "A new issue \u003cdon:core:dvrv-us-1:devo/11FVC3ScK:issue/91\u003e",
93+
"tnt__a_text_field": ""
94+
},
95+
"custom_schema_fragments": [
96+
"don:core:dvrv-us-1:devo/11FVC3ScK:tenant_fragment/503",
97+
"don:core:dvrv-us-1:devo/11FVC3ScK:custom_type_fragment/480"
98+
],
99+
"display_id": "ISS-98",
100+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:issue/98",
101+
"id_v1": "don:DEV-11FVC3ScK:issue:98",
102+
"modified_by": {
103+
"type": "dev_user",
104+
"display_handle": "shivansh-rai",
105+
"display_id": "DEVU-1",
106+
"display_name": "shivansh-rai",
107+
"email": "[email protected]",
108+
"full_name": "Shivansh Rai",
109+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/1",
110+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-1",
111+
"state": "active",
112+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Shivansh%20Rai.png"
113+
},
114+
"modified_date": "2025-07-02T13:04:12.1Z",
115+
"owned_by": [
116+
{
117+
"type": "dev_user",
118+
"display_handle": "gowtham-tg",
119+
"display_id": "DEVU-10",
120+
"display_name": "gowtham-tg",
121+
"email": "[email protected]",
122+
"full_name": "Gowtham Gopinath",
123+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/10",
124+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-10",
125+
"state": "active",
126+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Gowtham%20Gopinath.png"
127+
}
128+
],
129+
"priority": "p1",
130+
"priority_v2": {
131+
"id": 2,
132+
"label": "P1",
133+
"ordinal": 2
134+
},
135+
"references": [
136+
{
137+
"type": "issue",
138+
"display_id": "ISS-98",
139+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:issue/98",
140+
"id_v1": "don:DEV-11FVC3ScK:issue:98",
141+
"owned_by": [
142+
{
143+
"type": "dev_user",
144+
"display_handle": "gowtham-tg",
145+
"display_id": "DEVU-10",
146+
"display_name": "gowtham-tg",
147+
"email": "[email protected]",
148+
"full_name": "Gowtham Gopinath",
149+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/10",
150+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-10",
151+
"state": "active",
152+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Gowtham%20Gopinath.png"
153+
}
154+
],
155+
"priority": "p2",
156+
"priority_v2": {
157+
"id": 3,
158+
"label": "P2",
159+
"ordinal": 3
160+
},
161+
"stage": {
162+
"name": "prioritized",
163+
"stage": {
164+
"display_name": "Prioritized",
165+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:custom_stage/27",
166+
"name": "prioritized"
167+
}
168+
},
169+
"title": "issue with a subtype"
170+
}
171+
],
172+
"stage": {
173+
"display_name": "Prioritized",
174+
"name": "prioritized",
175+
"notes": "",
176+
"ordinal": 3600,
177+
"stage": {
178+
"display_name": "Prioritized",
179+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:custom_stage/27",
180+
"name": "prioritized"
181+
},
182+
"state": {
183+
"display_name": "Open",
184+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:custom_state/1",
185+
"is_final": false,
186+
"name": "open"
187+
}
188+
},
189+
"state": "open",
190+
"stock_schema_fragment": "don:core:dvrv-us-1:stock_sf/5774789",
191+
"subtype": "test",
192+
"title": "issue with a subtype"
193+
},
194+
"work": {
195+
"type": "issue",
196+
"applies_to_part": {
197+
"type": "product",
198+
"display_id": "PROD-2",
199+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:product/2",
200+
"id_v1": "don:DEV-11FVC3ScK:product:2",
201+
"name": "prod-foo",
202+
"owned_by": [
203+
{
204+
"type": "dev_user",
205+
"display_handle": "shivansh-rai",
206+
"display_id": "DEVU-1",
207+
"display_name": "shivansh-rai",
208+
"email": "[email protected]",
209+
"full_name": "Shivansh Rai",
210+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/1",
211+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-1",
212+
"state": "active",
213+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Shivansh%20Rai.png"
214+
}
215+
],
216+
"stage": {
217+
"name": ""
218+
}
219+
},
220+
"body": "\u003cdon:core:dvrv-us-1:devo/11FVC3ScK:issue/98\u003e",
221+
"created_by": {
222+
"type": "dev_user",
223+
"display_handle": "shivansh-rai",
224+
"display_id": "DEVU-1",
225+
"display_name": "shivansh-rai",
226+
"email": "[email protected]",
227+
"full_name": "Shivansh Rai",
228+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/1",
229+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-1",
230+
"state": "active",
231+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Shivansh%20Rai.png"
232+
},
233+
"created_date": "2025-06-14T13:20:46.963Z",
234+
"custom_fields": {
235+
"ctype__color": "Blue",
236+
"tnt__a_rich_text_field": "A new issue \u003cdon:core:dvrv-us-1:devo/11FVC3ScK:issue/91\u003e",
237+
"tnt__a_text_field": ""
238+
},
239+
"custom_schema_fragments": [
240+
"don:core:dvrv-us-1:devo/11FVC3ScK:tenant_fragment/503",
241+
"don:core:dvrv-us-1:devo/11FVC3ScK:custom_type_fragment/480"
242+
],
243+
"display_id": "ISS-98",
244+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:issue/98",
245+
"id_v1": "don:DEV-11FVC3ScK:issue:98",
246+
"modified_by": {
247+
"type": "dev_user",
248+
"display_handle": "shivansh-rai",
249+
"display_id": "DEVU-1",
250+
"display_name": "shivansh-rai",
251+
"email": "[email protected]",
252+
"full_name": "Shivansh Rai",
253+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/1",
254+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-1",
255+
"state": "active",
256+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Shivansh%20Rai.png"
257+
},
258+
"modified_date": "2025-07-02T13:07:40.704Z",
259+
"owned_by": [
260+
{
261+
"type": "dev_user",
262+
"display_handle": "gowtham-tg",
263+
"display_id": "DEVU-10",
264+
"display_name": "gowtham-tg",
265+
"email": "[email protected]",
266+
"full_name": "Gowtham Gopinath",
267+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/10",
268+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-10",
269+
"state": "active",
270+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Gowtham%20Gopinath.png"
271+
}
272+
],
273+
"priority": "p2",
274+
"priority_v2": {
275+
"id": 3,
276+
"label": "P2",
277+
"ordinal": 3
278+
},
279+
"references": [
280+
{
281+
"type": "issue",
282+
"display_id": "ISS-98",
283+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:issue/98",
284+
"id_v1": "don:DEV-11FVC3ScK:issue:98",
285+
"owned_by": [
286+
{
287+
"type": "dev_user",
288+
"display_handle": "gowtham-tg",
289+
"display_id": "DEVU-10",
290+
"display_name": "gowtham-tg",
291+
"email": "[email protected]",
292+
"full_name": "Gowtham Gopinath",
293+
"id": "don:identity:dvrv-us-1:devo/11FVC3ScK:devu/10",
294+
"id_v1": "don:DEV-11FVC3ScK:dev_user:DEVU-10",
295+
"state": "active",
296+
"thumbnail": "https://api.dev.devrev-eng.ai/internal/display-picture/Gowtham%20Gopinath.png"
297+
}
298+
],
299+
"priority": "p2",
300+
"priority_v2": {
301+
"id": 3,
302+
"label": "P2",
303+
"ordinal": 3
304+
},
305+
"stage": {
306+
"name": "prioritized",
307+
"stage": {
308+
"display_name": "Prioritized",
309+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:custom_stage/27",
310+
"name": "prioritized"
311+
}
312+
},
313+
"title": "issue with a subtype"
314+
}
315+
],
316+
"stage": {
317+
"display_name": "Prioritized",
318+
"name": "prioritized",
319+
"notes": "",
320+
"ordinal": 3600,
321+
"stage": {
322+
"display_name": "Prioritized",
323+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:custom_stage/27",
324+
"name": "prioritized"
325+
},
326+
"state": {
327+
"display_name": "Open",
328+
"id": "don:core:dvrv-us-1:devo/11FVC3ScK:custom_state/1",
329+
"is_final": false,
330+
"name": "open"
331+
}
332+
},
333+
"state": "open",
334+
"stock_schema_fragment": "don:core:dvrv-us-1:stock_sf/5774789",
335+
"subtype": "test",
336+
"title": "issue with a subtype"
337+
}
338+
},
339+
"type": "work_updated"
340+
}
341+
```

webhooks/go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module devrev-webhooks
2+
3+
go 1.24.1
4+
5+
require github.com/joho/godotenv v1.5.1

webhooks/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
2+
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=

0 commit comments

Comments
 (0)