Skip to content

Instantly share code, notes, and snippets.

@jeyemwey
Created September 22, 2020 07:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeyemwey/8e57cb5ee07b925133d50f537c91dbed to your computer and use it in GitHub Desktop.
Save jeyemwey/8e57cb5ee07b925133d50f537c91dbed to your computer and use it in GitHub Desktop.
Mumble-Fediverse-Bridge
package main
// This script pings a certain mumble server periodically (once per minute, per
// default). If the number of active connections changes from the last ping,
// the script will create a toot in Mastodon. It is therefore necassary to
// configure the `mastodonWriteEndpoint` and the `mastodonApiSecret`. Since a
// music bot resides in our mumble server, I set the default of connected users
// to one. This will only be respected the first time that the server starts.
//
// To execute the script, run `go run main.go` on a computer with configured go
// runtime. For simplicity reasons, I have my instance sitting in a screen
// shell. Bots are not always welcome, neither on the Mumble nor the Mastodon
// side - please check before running the bot.
//
// License: You are free to use this software. If you enhance the software and
// think that other people might benefit, please publish your modified code.
//
// © 2020, Jannik<jannik@outlook.com, Mastodon: @jannik@uelfte.club>
import (
"encoding/binary"
"fmt"
"net"
"net/http"
"strings"
"time"
)
type MumblePing struct {
Version uint32
Ident uint64
ConnectedUsers uint32
MaxUsers uint32
AllowedBandwidth uint32
}
func (t *MumblePing) FillMsg(msg []byte) {
t.Version = binary.BigEndian.Uint32(msg[0:4])
t.Ident = binary.BigEndian.Uint64(msg[4:12])
t.ConnectedUsers = binary.BigEndian.Uint32(msg[12:16])
t.MaxUsers = binary.BigEndian.Uint32(msg[16:20])
t.AllowedBandwidth = binary.BigEndian.Uint32(msg[20:24])
}
func main() {
mumbleHost := "chaos.jetzt:64738"
connectedUsers := uint32(1) // The musicbot is always online, so don't care about that
mastodonWriteEndpoint := "https://botsin.space/api/v1/statuses"
mastodonApiSecret := "THATS_A_SECRET" // Access token from https://botsin.space/settings/applications
s, err := net.ResolveUDPAddr("udp4", mumbleHost)
c, err := net.DialUDP("udp4", nil, s)
if err != nil {
fmt.Println(err)
return
}
defer c.Close()
for range time.Tick(1 * time.Minute) {
_, err := c.Write([]byte{
// Force 0
0x00, 0x00, 0x00, 0x00,
//Ident
0x23, 0x42, 0x13, 0x37,
0x23, 0x42, 0x13, 0x37,
})
if err != nil {
fmt.Println(err)
return
}
buffer := make([]byte, 24)
_, _, err = c.ReadFromUDP(buffer)
if err != nil {
fmt.Println(err)
return
}
t := MumblePing{}
t.FillMsg(buffer)
if t.ConnectedUsers != connectedUsers {
connectedUsers = t.ConnectedUsers
reqbody := fmt.Sprintf("{\"status\": \"There are currently %d users online!\"}", connectedUsers)
if connectedUsers == 1 {
reqbody = fmt.Sprintf("{\"status\": \"There is currently %d user online!\"}", connectedUsers)
}
fmt.Println(reqbody)
method := "POST"
payload := strings.NewReader(reqbody)
client := &http.Client{}
req, err := http.NewRequest(method, mastodonWriteEndpoint, payload)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", mastodonApiSecret))
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
defer res.Body.Close()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment