# Handle Alert via Webhook

## Alert Object <a href="#alert-object" id="alert-object"></a>

WatchTower will send each alert as a JSON object to the configured webhook URL via a POST request.

{% code title="Alert Object Example" %}

```json
{
    "id": "634cf5d77b42a046f68f5a5d",
    "botId": "634cf5d77b42a046f68f5a5e",
    "botName": "MyToken 500+",
    "projectId": "634cf5d77b42a046f68f5a5a",
    "projectName": "My Token",
    "userId": "634cf5d77b42a046f68f5a5f",
    "username": "John Doe",
    "template": "AbnormalTransferToken",
    "severity": "critical",
    "tx": ["6CfQwX7YwvA2bFRT8wfzZEtVEUbbrjUeMzBa9AbtThioHC6xfrfxSC3nCQWB5Y3BLV9cqadf69n9ApeBYhvwzNF1"],
    "detail": "The smart contract is involved in a transaction transferring 923750.55 Unknown Token. The token mint is 9Mu1Kaxbe2fehdDoeTJ5oD7XFQmEiZxzspEd3TZGkavx",
    "target": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
    "args": {"threshold": "500"},
    "isArchived": false,
    "created_at": "2022-12-06T17:10:21.672Z",
    "link": "https://pro.sec3.dev/alert/634cf5d77b42a046f68f5a5d"
}
```

{% endcode %}

## Sample webhook handler code <a href="#sample-webhook-handler-code" id="sample-webhook-handler-code"></a>

{% tabs %}
{% tab title="Go" %}

```go
package main

import (
	"log"
	"net/http"
	"encoding/json"
	"fmt"
	"time"
)

// Define the Sec3 WatchTower secret
// In the actual server, the secret should be put in the environmental variables
const SEC3_WATCHTOWER_SECRET = "your_secret"

type Alert struct {
	ID          string            `json:"id"`
	BotId       string            `json:"botId"`
	UserId      string            `json:"userId"`
	ProjectId   string            `json:"projectId"`
	Username    string            `json:"username"`
	ProjectName string            `json:"projectName"`
	BotName     string            `json:"botName"`
	Template    string            `json:"template"`
	Severity    string            `json:"severity"`
	Tx          []string          `json:"tx"`
	Detail      string            `json:"detail"`
	Targets     []string          `json:"targets"`
	Args        map[string]string `json:"args"`
	IsArchived  bool              `json:"isArchived"`
	CreatedAt   time.Time         `json:"created_at"`
	Link        string            `json:"link"`
}

func sec3WebhookHandler(w http.ResponseWriter, r *http.Request) {
	// Verify the incoming request. If the secret is empty or does not match
	// with the one you set, return 401 status code
	incomingSecret := r.Header.Get("X-Sec3-Watchtower-Secret")
	if incomingSecret == "" || incomingSecret != SEC3_WATCHTOWER_SECRET {
		http.Error(w, "unauthorized", http.StatusUnauthorized)
		return
	}
	
	// Declare a new Alert struct.
	var alert Alert

	// Try to decode the request body into the struct. If there is an error,
	// respond to the client with the error message and a 400 status code.
	err = json.NewDecoder(r.Body).Decode(&alert)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Do something with the alert...
	fmt.Printf("Alert:\n %+v\n", alert)
}

func main() {
	http.HandleFunc("/sec3_webhook", sec3WebhookHandler)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal(err)
	}
}
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
// This example uses express.js framework. See https://expressjs.com
const express = require('express');
const app = express();
const port = 3000;

// Define the sec3 WatchTower secret
// In the actual server, the secret should be put in the environmental variables
const SEC3_WATCHTOWER_SECRET = "your_secret";

// Verify the incoming request. If the secret is empty or does not match
// with the one you set, return 401 status code
app.use((req, res, next) => {
  const incomingSecret = req.header("X-Sec3-Watchtower-Secret");
  if (incomingSecret != SEC3_WATCHTOWER_SECRET) {
    res.sendStatus(401);
    return;
  }
  next();
})

app.use(express.json());

app.post('/sec3_webhook', (req, res) => {
  const alert = req.body;

  // Do something with the alert...
  console.log(alert);
  res.sendStatus(200);
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://doc.sec3.dev/sec3-watchtower/handle-alert-via-webhook.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
