crossover

This commit is contained in:
KS Jannette
2026-02-27 15:07:43 -05:00
parent 0adfd70853
commit 5f81a4b1cc
31 changed files with 2890 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
package notifications
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"time"
)
type AlertMetadata struct {
TxHash string
AddressLabel string
AlertType string
Address string
}
type discordEmbed struct {
Title string `json:"title"`
Description string `json:"description"`
Color int `json:"color"`
Fields []discordField `json:"fields"`
Timestamp string `json:"timestamp"`
Footer discordFooter `json:"footer"`
}
type discordField struct {
Name string `json:"name"`
Value string `json:"value"`
Inline bool `json:"inline"`
}
type discordFooter struct {
Text string `json:"text"`
}
type discordPayload struct {
Content *string `json:"content"`
Embeds []discordEmbed `json:"embeds,omitempty"`
}
func SendDiscordNotification(webhookURL, message string, meta AlertMetadata) (bool, error) {
fields := []discordField{
{Name: "Address", Value: meta.AddressLabel, Inline: true},
{Name: "Blockchain Address", Value: fmt.Sprintf("`%s`", meta.Address), Inline: false},
}
if meta.TxHash != "" {
fields = append(fields, discordField{
Name: "Transaction",
Value: fmt.Sprintf("[View on Etherscan](https://etherscan.io/tx/%s)", meta.TxHash),
Inline: false,
})
}
payload := discordPayload{
Content: nil,
Embeds: []discordEmbed{
{
Title: "Koin Ping Alert",
Description: message,
Color: colorForAlertType(meta.AlertType),
Fields: fields,
Timestamp: time.Now().UTC().Format(time.RFC3339),
Footer: discordFooter{Text: "Koin Ping"},
},
},
}
body, err := json.Marshal(payload)
if err != nil {
return false, fmt.Errorf("marshal discord payload: %w", err)
}
resp, err := http.Post(webhookURL, "application/json", bytes.NewReader(body))
if err != nil {
log.Printf("Failed to send Discord notification: %v", err)
return false, err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
log.Printf("Discord webhook failed: HTTP %d", resp.StatusCode)
return false, fmt.Errorf("discord webhook failed: HTTP %d", resp.StatusCode)
}
return true, nil
}
func TestDiscordWebhook(webhookURL string) (bool, error) {
payload := map[string]string{
"content": "Koin Ping test notification - Your Discord webhook is configured correctly!",
}
body, err := json.Marshal(payload)
if err != nil {
return false, err
}
resp, err := http.Post(webhookURL, "application/json", bytes.NewReader(body))
if err != nil {
log.Printf("Discord webhook test failed: %v", err)
return false, err
}
defer resp.Body.Close()
return resp.StatusCode >= 200 && resp.StatusCode < 300, nil
}
func colorForAlertType(alertType string) int {
switch alertType {
case "incoming_tx":
return 0x00ff00 // Green
case "outgoing_tx":
return 0xff9900 // Orange
case "large_transfer":
return 0xff0000 // Red
case "balance_below":
return 0xff0000 // Red
default:
return 0x0099ff // Blue
}
}