mirror of
https://github.com/arnaucube/twitterDM-to-matrix.git
synced 2026-02-07 03:36:47 +01:00
it works
This commit is contained in:
29
.gitignore
vendored
Normal file
29
.gitignore
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
||||||
|
|
||||||
|
|
||||||
|
twitterConfig.json
|
||||||
|
matrixConfig.json
|
||||||
|
temp
|
||||||
33
README.md
Normal file
33
README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# twitterDM-to-matrix [](https://goreportcard.com/report/github.com/arnaucode/twitterDM-to-matrix)
|
||||||
|
|
||||||
|
bridge to send the received twitter Direct Messages (https://twitter.com) to a Matrix room (https://matrix.org), written in Go
|
||||||
|
|
||||||
|
|
||||||
|
needs a twitterConfig.json file on the /build folder with the content:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"consumer_key": "xxxxxxxxxxxxxxxx",
|
||||||
|
"consumer_secret": "xxxxxxxxxxxxxxxx",
|
||||||
|
"access_token_key": "xxxxxxxxxxxxxxxx",
|
||||||
|
"access_token_secret": "xxxxxxxxxxxxxxxx"
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
and a matrixConfig.json file on the /build folder with the content:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"room_id": "xxxxx",
|
||||||
|
"user": "xxxxx",
|
||||||
|
"password": "xxxxx",
|
||||||
|
"server": "https://xxxxx.xxxxx"
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
to run it:
|
||||||
|
- go to the /build folder
|
||||||
|
- open terminal
|
||||||
|
- execute the script with:
|
||||||
|
```
|
||||||
|
./twitterDM-to-matrix
|
||||||
|
```
|
||||||
6
build/matrixConfigDEMO.json
Normal file
6
build/matrixConfigDEMO.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"room_id": "xxxxx",
|
||||||
|
"user": "xxxxx",
|
||||||
|
"password": "xxxxx",
|
||||||
|
"server": "https://xxxxx.xxxxx"
|
||||||
|
}
|
||||||
7
build/twitterConfigDEMO.json
Normal file
7
build/twitterConfigDEMO.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"screenName": "xxxxx",
|
||||||
|
"consumer_key": "xxxxx",
|
||||||
|
"consumer_secret": "xxxxx",
|
||||||
|
"access_token": "xxxxx",
|
||||||
|
"access_token_secret": "xxxxx"
|
||||||
|
}
|
||||||
BIN
build/twitterDM-to-matrix
Executable file
BIN
build/twitterDM-to-matrix
Executable file
Binary file not shown.
57
color.go
Normal file
57
color.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
//Color struct, defines the color
|
||||||
|
type Color struct{}
|
||||||
|
|
||||||
|
var c Color
|
||||||
|
|
||||||
|
//DarkGray color
|
||||||
|
func (c Color) DarkGray(t string) {
|
||||||
|
fmt.Print("\x1b[30;1m") //dark gray
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Red color
|
||||||
|
func (c Color) Red(t string) {
|
||||||
|
fmt.Print("\x1b[31;1m") //red
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Green color
|
||||||
|
func (c Color) Green(t string) {
|
||||||
|
fmt.Print("\x1b[32;1m") //green
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Yellow color
|
||||||
|
func (c Color) Yellow(t string) {
|
||||||
|
fmt.Print("\x1b[33;1m") //yellow
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Blue color
|
||||||
|
func (c Color) Blue(t string) {
|
||||||
|
fmt.Print("\x1b[34;1m") //blue
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Purple color
|
||||||
|
func (c Color) Purple(t string) {
|
||||||
|
fmt.Print("\x1b[35;1m") //purple
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
|
|
||||||
|
//Cyan color
|
||||||
|
func (c Color) Cyan(t string) {
|
||||||
|
fmt.Print("\x1b[36;1m") //cyan
|
||||||
|
fmt.Println(t)
|
||||||
|
fmt.Print("\x1b[0m") //defaultColor
|
||||||
|
}
|
||||||
31
main.go
Normal file
31
main.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const version = "0.1-dev"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c.Green("twitterDM-to-matrix")
|
||||||
|
c.Yellow("version: " + version)
|
||||||
|
c.Green("bridge twitter DM to Matrix")
|
||||||
|
fmt.Println("configuring")
|
||||||
|
|
||||||
|
c.Purple("------matrix------")
|
||||||
|
readMatrixConfig()
|
||||||
|
loginMatrix()
|
||||||
|
fmt.Print("matrix token: ")
|
||||||
|
c.Cyan(matrixToken.AccessToken)
|
||||||
|
fmt.Println("")
|
||||||
|
|
||||||
|
c.Purple("------twitter------")
|
||||||
|
client := readTwitterConfigTokensAndConnect()
|
||||||
|
user := getUserData(client)
|
||||||
|
printTwitterUserData(user)
|
||||||
|
fmt.Println("")
|
||||||
|
|
||||||
|
c.Purple("------starting to listen------")
|
||||||
|
|
||||||
|
stream(client)
|
||||||
|
}
|
||||||
86
matrix.go
Normal file
86
matrix.go
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
//MatrixConfig stores the data from json matrixConfig.json file
|
||||||
|
type MatrixConfig struct {
|
||||||
|
RoomId string `json:"room_id"`
|
||||||
|
User string `json:"user"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Server string `json:"server"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//MatrixToken stores the token data from matrix
|
||||||
|
type MatrixToken struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
Server string `json:"server"`
|
||||||
|
UserId string `json:"user_id"`
|
||||||
|
DeviceId string `json:"device_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var matrixConfig MatrixConfig
|
||||||
|
var matrixToken MatrixToken
|
||||||
|
|
||||||
|
func readMatrixConfig() {
|
||||||
|
file, e := ioutil.ReadFile("matrixConfig.json")
|
||||||
|
if e != nil {
|
||||||
|
fmt.Println("error:", e)
|
||||||
|
}
|
||||||
|
content := string(file)
|
||||||
|
json.Unmarshal([]byte(content), &matrixConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loginMatrix() {
|
||||||
|
url := matrixConfig.Server + "/_matrix/client/r0/login"
|
||||||
|
jsonStr := `{
|
||||||
|
"type":"m.login.password",
|
||||||
|
"user":"` + matrixConfig.User + `",
|
||||||
|
"password":"` + matrixConfig.Password + `"
|
||||||
|
}`
|
||||||
|
b := strings.NewReader(jsonStr)
|
||||||
|
req, _ := http.NewRequest("POST", url, b)
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
res, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
body, _ := ioutil.ReadAll(res.Body)
|
||||||
|
|
||||||
|
json.Unmarshal([]byte(body), &matrixToken)
|
||||||
|
|
||||||
|
}
|
||||||
|
func matrixSendMsg(senderScreenName string, message string, createdAt string) {
|
||||||
|
txnId := strconv.Itoa(rand.Int())
|
||||||
|
c.Green(txnId)
|
||||||
|
url := matrixConfig.Server + "/_matrix/client/r0/rooms/" + matrixConfig.RoomId + "/send/m.room.message/" + txnId + "?access_token=" + matrixToken.AccessToken
|
||||||
|
jsonStr := `{
|
||||||
|
"body":"[NEW DM] - at ` + createdAt + `\n@` + senderScreenName + `: ` + message + `",
|
||||||
|
"msgtype":"m.text"
|
||||||
|
}`
|
||||||
|
b := strings.NewReader(jsonStr)
|
||||||
|
req, _ := http.NewRequest("PUT", url, b)
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
res, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
body, _ := ioutil.ReadAll(res.Body)
|
||||||
|
|
||||||
|
fmt.Println(string(body))
|
||||||
|
|
||||||
|
fmt.Println(createdAt)
|
||||||
|
fmt.Print("received DM sent to Matrix: ")
|
||||||
|
c.Green(message)
|
||||||
|
|
||||||
|
}
|
||||||
43
twitterConfigClient.go
Normal file
43
twitterConfigClient.go
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/dghubble/go-twitter/twitter"
|
||||||
|
"github.com/dghubble/oauth1"
|
||||||
|
)
|
||||||
|
|
||||||
|
//TwitterConfig stores the data from json twitterConfig.json file
|
||||||
|
type TwitterConfig struct {
|
||||||
|
ScreenName string `json:"screenName"`
|
||||||
|
ConsumerKey string `json:"consumer_key"`
|
||||||
|
ConsumerSecret string `json:"consumer_secret"`
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
AccessTokenSecret string `json:"access_token_secret"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var twitterConfig TwitterConfig
|
||||||
|
|
||||||
|
func readTwitterConfigTokensAndConnect() (client *twitter.Client) {
|
||||||
|
|
||||||
|
file, e := ioutil.ReadFile("twitterConfig.json")
|
||||||
|
if e != nil {
|
||||||
|
fmt.Println("error:", e)
|
||||||
|
}
|
||||||
|
content := string(file)
|
||||||
|
json.Unmarshal([]byte(content), &twitterConfig)
|
||||||
|
fmt.Println("twitterConfig.json read comlete")
|
||||||
|
|
||||||
|
fmt.Print("connecting to twitter api --> ")
|
||||||
|
configu := oauth1.NewConfig(twitterConfig.ConsumerKey, twitterConfig.ConsumerSecret)
|
||||||
|
token := oauth1.NewToken(twitterConfig.AccessToken, twitterConfig.AccessTokenSecret)
|
||||||
|
httpClient := configu.Client(oauth1.NoContext, token)
|
||||||
|
// twitter client
|
||||||
|
client = twitter.NewClient(httpClient)
|
||||||
|
|
||||||
|
fmt.Println("connection successful")
|
||||||
|
|
||||||
|
return client
|
||||||
|
}
|
||||||
46
twitterStreamDM.go
Normal file
46
twitterStreamDM.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/dghubble/go-twitter/twitter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func stream(client *twitter.Client) {
|
||||||
|
// Convenience Demux demultiplexed stream messages
|
||||||
|
demux := twitter.NewSwitchDemux()
|
||||||
|
|
||||||
|
demux.All = func(message interface{}) {
|
||||||
|
//fmt.Println(message)
|
||||||
|
}
|
||||||
|
demux.DM = func(dm *twitter.DirectMessage) {
|
||||||
|
if dm.SenderScreenName != twitterConfig.ScreenName {
|
||||||
|
matrixSendMsg(dm.SenderScreenName, dm.Text, dm.CreatedAt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
demux.Event = func(event *twitter.Event) {
|
||||||
|
//fmt.Printf("%#v\n", event)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Starting Stream...")
|
||||||
|
|
||||||
|
streamUserParams := &twitter.StreamUserParams{}
|
||||||
|
stream, err := client.Streams.User(streamUserParams)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Receive messages until stopped or stream quits
|
||||||
|
demux.HandleChan(stream.Messages)
|
||||||
|
|
||||||
|
ch := make(chan os.Signal)
|
||||||
|
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
log.Println(<-ch)
|
||||||
|
|
||||||
|
fmt.Println("Stopping Stream...")
|
||||||
|
stream.Stop()
|
||||||
|
}
|
||||||
31
twitterUserOperations.go
Normal file
31
twitterUserOperations.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/dghubble/go-twitter/twitter"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getUserData(client *twitter.Client) *twitter.User {
|
||||||
|
// Verify Credentials
|
||||||
|
verifyParams := &twitter.AccountVerifyParams{
|
||||||
|
SkipStatus: twitter.Bool(true),
|
||||||
|
IncludeEmail: twitter.Bool(true),
|
||||||
|
}
|
||||||
|
user, _, _ := client.Accounts.VerifyCredentials(verifyParams)
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
func printTwitterUserData(user *twitter.User) {
|
||||||
|
fmt.Print("username: ")
|
||||||
|
c.Cyan(user.Name + " @" + user.ScreenName)
|
||||||
|
if user.Email != "" {
|
||||||
|
fmt.Print("Email ")
|
||||||
|
c.Red(user.Email)
|
||||||
|
}
|
||||||
|
if user.Location != "" {
|
||||||
|
fmt.Print("Location: ")
|
||||||
|
c.Red(user.Location)
|
||||||
|
}
|
||||||
|
fmt.Print("user created on: ")
|
||||||
|
c.Cyan(user.CreatedAt)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user