Initial config structs and example config, some whatsapp testing
This commit is contained in:
parent
c84b5dd5dc
commit
ace08205d9
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
.idea
|
||||
*.session
|
||||
|
76
config/bridge.go
Normal file
76
config/bridge.go
Normal file
@ -0,0 +1,76 @@
|
||||
// mautrix-whatsapp - A Matrix-Whatsapp puppeting bridge.
|
||||
// Copyright (C) 2018 Tulir Asokan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type BridgeConfig struct {
|
||||
RawUsernameTemplate string `yaml:"username_template"`
|
||||
RawDisplaynameTemplate string `yaml:"displayname_template"`
|
||||
UsernameTemplate *template.Template `yaml:"-"`
|
||||
DisplaynameTemplate *template.Template `yaml:"-"`
|
||||
}
|
||||
|
||||
func (bc BridgeConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
err := unmarshal(bc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bc.UsernameTemplate, err = template.New("username").Parse(bc.RawUsernameTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bc.DisplaynameTemplate, err = template.New("displayname").Parse(bc.RawDisplaynameTemplate)
|
||||
return err
|
||||
}
|
||||
|
||||
type DisplaynameTemplateArgs struct {
|
||||
Displayname string
|
||||
}
|
||||
|
||||
type UsernameTemplateArgs struct {
|
||||
Receiver string
|
||||
UserID string
|
||||
}
|
||||
|
||||
func (bc BridgeConfig) FormatDisplayname(displayname string) string {
|
||||
var buf bytes.Buffer
|
||||
bc.DisplaynameTemplate.Execute(&buf, DisplaynameTemplateArgs{
|
||||
Displayname: displayname,
|
||||
})
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (bc BridgeConfig) FormatUsername(receiver, userID string) string {
|
||||
var buf bytes.Buffer
|
||||
bc.UsernameTemplate.Execute(&buf, UsernameTemplateArgs{
|
||||
Receiver: receiver,
|
||||
UserID: userID,
|
||||
})
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (bc BridgeConfig) MarshalYAML() (interface{}, error) {
|
||||
bc.RawDisplaynameTemplate = bc.FormatDisplayname("{{.Displayname}}")
|
||||
bc.RawUsernameTemplate = bc.FormatUsername("{{.Receiver}}", "{{.UserID}}")
|
||||
return bc, nil
|
||||
}
|
81
config/config.go
Normal file
81
config/config.go
Normal file
@ -0,0 +1,81 @@
|
||||
// mautrix-whatsapp - A Matrix-Whatsapp puppeting bridge.
|
||||
// Copyright (C) 2018 Tulir Asokan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"maunium.net/go/mautrix-appservice"
|
||||
"io/ioutil"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Homeserver struct {
|
||||
Address string `yaml:"address"`
|
||||
Domain string `yaml:"domain"`
|
||||
} `yaml:"homeserver"`
|
||||
|
||||
AppService struct {
|
||||
Address string `yaml:"address"`
|
||||
Hostname string `yaml:"hostname"`
|
||||
Port uint16 `yaml:"port"`
|
||||
|
||||
Database string `yaml:"database"`
|
||||
|
||||
ID string `yaml:"id"`
|
||||
Bot struct {
|
||||
Username string `yaml:"username"`
|
||||
Displayname string `yaml:"displayname"`
|
||||
Avatar string `yaml:"avatar"`
|
||||
} `yaml:"bot"`
|
||||
|
||||
ASToken string `yaml:"as_token"`
|
||||
HSToken string `yaml:"hs_token"`
|
||||
} `yaml:"appservice"`
|
||||
|
||||
Bridge BridgeConfig `yaml:"bridge"`
|
||||
|
||||
Logging appservice.LogConfig `yaml:"logging"`
|
||||
}
|
||||
|
||||
func Load(path string) (*Config, error) {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config = &Config{}
|
||||
err = yaml.Unmarshal(data, config)
|
||||
return config, err
|
||||
}
|
||||
|
||||
func (config *Config) Save(path string) error {
|
||||
data, err := yaml.Marshal(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(path, data, 0600)
|
||||
}
|
||||
|
||||
func (config *Config) Appservice() (*appservice.Config, error) {
|
||||
as := appservice.Create()
|
||||
as.LogConfig = config.Logging
|
||||
as.HomeserverDomain = config.Homeserver.Domain
|
||||
as.HomeserverURL = config.Homeserver.Address
|
||||
var err error
|
||||
as.Registration, err = config.GetRegistration()
|
||||
return as, err
|
||||
}
|
62
config/registration.go
Normal file
62
config/registration.go
Normal file
@ -0,0 +1,62 @@
|
||||
// mautrix-whatsapp - A Matrix-Whatsapp puppeting bridge.
|
||||
// Copyright (C) 2018 Tulir Asokan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"maunium.net/go/mautrix-appservice"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func (config *Config) NewRegistration() (*appservice.Registration, error) {
|
||||
registration := appservice.CreateRegistration("mautrix-whatsapp")
|
||||
|
||||
err := config.copyToRegistration(registration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config.AppService.ASToken = registration.AppToken
|
||||
config.AppService.HSToken = registration.ServerToken
|
||||
return registration, nil
|
||||
}
|
||||
|
||||
func (config *Config) GetRegistration() (*appservice.Registration, error) {
|
||||
registration := appservice.CreateRegistration("mautrix-whatsapp")
|
||||
|
||||
err := config.copyToRegistration(registration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
registration.AppToken = config.AppService.ASToken
|
||||
registration.ServerToken = config.AppService.HSToken
|
||||
return registration, nil
|
||||
}
|
||||
|
||||
func (config *Config) copyToRegistration(registration *appservice.Registration) error {
|
||||
registration.ID = config.AppService.ID
|
||||
registration.URL = config.AppService.Address
|
||||
registration.RateLimited = false
|
||||
registration.SenderLocalpart = config.AppService.Bot.Username
|
||||
|
||||
userIDRegex, err := regexp.Compile(config.Bridge.FormatUsername("[0-9]+", "[0-9]+"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
registration.Namespaces.RegisterUserIDs(userIDRegex, true)
|
||||
return nil
|
||||
}
|
60
example-config.yaml
Normal file
60
example-config.yaml
Normal file
@ -0,0 +1,60 @@
|
||||
# Homeserver details.
|
||||
homeserver:
|
||||
# The address that this appservice can use to connect to the homeserver.
|
||||
address: https://matrix.org
|
||||
# The domain of the homeserver (for MXIDs, etc).
|
||||
domain: matrix.org
|
||||
|
||||
# Application service host/registration related details.
|
||||
# Changing these values requires regeneration of the registration.
|
||||
appservice:
|
||||
# The address that the homeserver can use to connect to this appservice.
|
||||
address: http://localhost:8080
|
||||
|
||||
# The hostname and port where this appservice should listen.
|
||||
hostname: 0.0.0.0
|
||||
port: 8080
|
||||
|
||||
# The full URI to the database. Only SQLite is currently supported.
|
||||
database: sqlite:///mautrix-whatsapp.db
|
||||
|
||||
# The unique ID of this appservice.
|
||||
id: whatsapp
|
||||
# Appservice bot details.
|
||||
bot:
|
||||
# Username of the appservice bot.
|
||||
username: whatsappbot
|
||||
# Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty
|
||||
# to leave display name/avatar as-is.
|
||||
displayname: WhatsApp bridge bot
|
||||
avatar: mxc://maunium.net/NeXNQarUbrlYBiPCpprYsRqr
|
||||
|
||||
# Authentication tokens for AS <-> HS communication. Autogenerated; do not modify.
|
||||
as_token: "This value is generated when generating the registration"
|
||||
hs_token: "This value is generated when generating the registration"
|
||||
|
||||
# Bridge config. Currently unused.
|
||||
bridge:
|
||||
# Localpart template of MXIDs for Whatsapp users.
|
||||
# {{.receiver}} is replaced with the Whatsapp user ID of the Matrix user receiving messages.
|
||||
# {{.userid}} is replaced with the user ID of the Whatsapp user.
|
||||
username_template: "whatsapp_{{.Receiver}}_{{.UserID}}"
|
||||
# Displayname template for Whatsapp users.
|
||||
# {{.displayname}} is replaced with the display name of the Whatsapp user.
|
||||
displayname_template: "{{.Displayname}}"
|
||||
|
||||
# Logging config.
|
||||
logging:
|
||||
# The directory for log files. Will be created if not found.
|
||||
directory: ./logs
|
||||
# Available variables: .date for the file date and .index for different log files on the same day.
|
||||
file_name_format: {{.date}}-{{.index}.log
|
||||
# Date format for file names in the Go time format: https://golang.org/pkg/time/#pkg-constants
|
||||
file_date_format: 2006-01-02
|
||||
# Log file permissions.
|
||||
file_mode: 0600
|
||||
# Timestamp format for log entries in the Go time format.
|
||||
timestamp_format: Jan _2, 2006 15:04:05
|
||||
# Minimum severity for log messages.
|
||||
# Options: debug, info, warn, error, fatal
|
||||
print_level: info
|
97
main.go
97
main.go
@ -1,4 +1,4 @@
|
||||
// mautrix-whatsapp - A puppeting Matrix-Whatsapp bridge.
|
||||
// mautrix-whatsapp - A Matrix-Whatsapp puppeting bridge.
|
||||
// Copyright (C) 2018 Tulir Asokan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
@ -16,6 +16,99 @@
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/Rhymen/go-whatsapp"
|
||||
"time"
|
||||
"fmt"
|
||||
"os"
|
||||
"bufio"
|
||||
"encoding/gob"
|
||||
"github.com/mdp/qrterminal"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
wac, err := whatsapp.NewConn(20 * time.Second)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
wac.AddHandler(myHandler{})
|
||||
|
||||
sess, err := LoadSession("whatsapp.session")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
sess, err = Login(wac)
|
||||
} else {
|
||||
sess, err = wac.RestoreSession(sess)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
SaveSession(sess, "whatsapp.session")
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
fmt.Print("receiver> ")
|
||||
receiver, _ := reader.ReadString('\n')
|
||||
fmt.Print("message> ")
|
||||
message, _ := reader.ReadString('\n')
|
||||
wac.Send(whatsapp.TextMessage{
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: fmt.Sprintf("%s@s.whatsapp.net", receiver),
|
||||
},
|
||||
Text: message,
|
||||
})
|
||||
fmt.Println(receiver, message)
|
||||
}
|
||||
}
|
||||
|
||||
func Login(wac *whatsapp.Conn) (whatsapp.Session, error) {
|
||||
qrChan := make(chan string)
|
||||
go func() {
|
||||
qrterminal.Generate(<-qrChan, qrterminal.L, os.Stdout)
|
||||
}()
|
||||
return wac.Login(qrChan)
|
||||
}
|
||||
|
||||
func SaveSession(session whatsapp.Session, fileName string) {
|
||||
file, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
enc := gob.NewEncoder(file)
|
||||
enc.Encode(session)
|
||||
}
|
||||
|
||||
func LoadSession(fileName string) (sess whatsapp.Session, err error) {
|
||||
file, err := os.OpenFile(fileName, os.O_RDONLY, 0600)
|
||||
if err != nil {
|
||||
return sess, err
|
||||
}
|
||||
|
||||
dec := gob.NewDecoder(file)
|
||||
dec.Decode(sess)
|
||||
return
|
||||
}
|
||||
|
||||
type myHandler struct{}
|
||||
|
||||
func (myHandler) HandleError(err error) {
|
||||
fmt.Fprintf(os.Stderr, "%v", err)
|
||||
}
|
||||
|
||||
func (myHandler) HandleTextMessage(message whatsapp.TextMessage) {
|
||||
fmt.Println(message)
|
||||
}
|
||||
|
||||
func (myHandler) HandleImageMessage(message whatsapp.ImageMessage) {
|
||||
fmt.Println(message)
|
||||
}
|
||||
|
||||
func (myHandler) HandleVideoMessage(message whatsapp.VideoMessage) {
|
||||
fmt.Println(message)
|
||||
}
|
||||
|
||||
func (myHandler) HandleJsonMessage(message string) {
|
||||
fmt.Println(message)
|
||||
}
|
||||
|
21
matrix.go
Normal file
21
matrix.go
Normal file
@ -0,0 +1,21 @@
|
||||
// mautrix-whatsapp - A Matrix-Whatsapp puppeting bridge.
|
||||
// Copyright (C) 2018 Tulir Asokan
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
func InitMatrix() {
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user