init
This commit is contained in:
commit
0f70db9ead
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
result
|
||||
pots
|
||||
.direnv
|
26
flake.lock
generated
Normal file
26
flake.lock
generated
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1673226411,
|
||||
"narHash": "sha256-b6cGb5Ln7Zy80YO66+cbTyGdjZKtkoqB/iIIhDX9gRA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "aa1d74709f5dac623adb4d48fdfb27cc2c92a4d4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-unstable",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
38
flake.nix
Normal file
38
flake.nix
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
description = "pots: a tailscale pushover webhooker";
|
||||
|
||||
inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
supportedSystems =
|
||||
[ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
|
||||
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
|
||||
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
|
||||
in {
|
||||
packages = forAllSystems (system:
|
||||
let pkgs = nixpkgsFor.${system};
|
||||
in {
|
||||
pots = pkgs.buildGoModule {
|
||||
pname = "pots";
|
||||
version = "v0.0.1";
|
||||
src = ./.;
|
||||
vendorHash = "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo=";
|
||||
};
|
||||
});
|
||||
|
||||
defaultPackage = forAllSystems (system: self.packages.${system}.pots);
|
||||
devShells = forAllSystems (system:
|
||||
let pkgs = nixpkgsFor.${system};
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
shellHook = ''
|
||||
PS1='\u@\h:\@; '
|
||||
echo "Go `${pkgs.go}/bin/go version`"
|
||||
'';
|
||||
nativeBuildInputs = with pkgs; [ git go gopls go-tools jo jq ];
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
155
main.go
Normal file
155
main.go
Normal file
@ -0,0 +1,155 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type LogEntry struct {
|
||||
Timestamp string `json:"timestamp"`
|
||||
Version int `json:"version"`
|
||||
Type string `json:"type"`
|
||||
Tailnet string `json:"tailnet"`
|
||||
Message string `json:"message"`
|
||||
Data Data `json:"data"`
|
||||
}
|
||||
type Data struct {
|
||||
NodeID string `json:"nodeID,omitempty"`
|
||||
DeviceName string `json:"deviceName,omitempty"`
|
||||
ManagedBy string `json:"managedBy,omitempty"`
|
||||
Actor string `json:"actor,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
type TSLogs []LogEntry
|
||||
|
||||
// Push represents a message sent to the Pushover api
|
||||
type Push struct {
|
||||
Token string `json:"token"`
|
||||
User string `json:"user"`
|
||||
Message string `json:"message"`
|
||||
Device string `json:"device,omitempty"`
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
URLTitle string `json:"url_title,omitempty"`
|
||||
Priority int `json:"priority,omitempty"`
|
||||
Sound string `json:"sound,omitempty"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
// PushResponse is a response from the Pushover api
|
||||
type PushResponse struct {
|
||||
Status int `json:"status,omitempty"`
|
||||
Request string `json:"request,omitempty"`
|
||||
User string `json:"user,omitempty"`
|
||||
Errors []string `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
type apiHandler struct{}
|
||||
|
||||
var (
|
||||
appToken = os.Getenv("PUSHOVER_TOKEN")
|
||||
userToken = os.Getenv("PUSHOVER_USER")
|
||||
potsToken = os.Getenv("POTS_TOKEN")
|
||||
client = *http.DefaultClient
|
||||
)
|
||||
|
||||
func sendPush(p *Push) error {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
if err := json.NewEncoder(buf).Encode(p); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", "https://api.pushover.net/1/messages.json", buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
|
||||
var resBody PushResponse
|
||||
if err = json.NewDecoder(res.Body).Decode(&resBody); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(resBody.Errors) > 0 {
|
||||
return fmt.Errorf("%s", strings.Join(resBody.Errors, ", "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (apiHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
if req.Method != "POST" {
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
token := path.Base(req.URL.Path)
|
||||
if token != potsToken {
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(req.Body)
|
||||
var tsLogs TSLogs
|
||||
err := decoder.Decode(&tsLogs)
|
||||
if err != nil {
|
||||
http.Error(w, "invalid data", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
for _, t := range tsLogs {
|
||||
var push = &Push{
|
||||
Token: appToken,
|
||||
User: userToken,
|
||||
Timestamp: time.Now(),
|
||||
Title: t.Message,
|
||||
Message: t.Type,
|
||||
URL: t.Data.URL,
|
||||
}
|
||||
err := sendPush(push)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
listen := flag.String("listen", ":8888", "listen string")
|
||||
flag.Parse()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/api/", apiHandler{})
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
|
||||
log.Println(req.URL.Path)
|
||||
if req.URL.Path != "/" {
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, `<a href="https://suah.dev/pots">suah.dev/pots</a>`)
|
||||
})
|
||||
|
||||
s := &http.Server{
|
||||
Addr: *listen,
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
log.Fatal(s.ListenAndServe())
|
||||
}
|
Loading…
Reference in New Issue
Block a user