forked from danielgross/whatsapp-gpt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
54e7050
commit 7fbb5d4
Showing
5 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
# whatsapp-gpt | ||
* You'll need to run WhatsApp from a phone number using the golang library I'm using. | ||
* You'll run a dedicated browser in another window that's controlling ChatGPT. | ||
* This this the end of the readme file for now; it is a bit sparse. Will add more later. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module example.com/m | ||
|
||
go 1.19 | ||
|
||
require ( | ||
filippo.io/edwards25519 v1.0.0 // indirect | ||
github.com/gorilla/websocket v1.5.0 // indirect | ||
github.com/mattn/go-sqlite3 v1.14.16 // indirect | ||
github.com/mdp/qrterminal v1.0.1 // indirect | ||
github.com/mdp/qrterminal/v3 v3.0.0 // indirect | ||
go.mau.fi/libsignal v0.0.0-20221015105917-d970e7c3c9cf // indirect | ||
go.mau.fi/whatsmeow v0.0.0-20221202110551-e067ee7293b0 // indirect | ||
golang.org/x/crypto v0.0.0-20221012134737-56aed061732a // indirect | ||
google.golang.org/protobuf v1.28.1 // indirect | ||
rsc.io/qr v0.2.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= | ||
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= | ||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= | ||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= | ||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= | ||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | ||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= | ||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= | ||
github.com/mdp/qrterminal v1.0.1 h1:07+fzVDlPuBlXS8tB0ktTAyf+Lp1j2+2zK3fBOL5b7c= | ||
github.com/mdp/qrterminal v1.0.1/go.mod h1:Z33WhxQe9B6CdW37HaVqcRKzP+kByF3q/qLxOGe12xQ= | ||
github.com/mdp/qrterminal/v3 v3.0.0 h1:ywQqLRBXWTktytQNDKFjhAvoGkLVN3J2tAFZ0kMd9xQ= | ||
github.com/mdp/qrterminal/v3 v3.0.0/go.mod h1:NJpfAs7OAm77Dy8EkWrtE4aq+cE6McoLXlBqXQEwvE0= | ||
go.mau.fi/libsignal v0.0.0-20221015105917-d970e7c3c9cf h1:mzPxXBgDPHKDHMVV1tIWh7lwCiRpzCsXC0gNRX+K07c= | ||
go.mau.fi/libsignal v0.0.0-20221015105917-d970e7c3c9cf/go.mod h1:XCjaU93vl71YNRPn059jMrK0xRDwVO5gKbxoPxow9mQ= | ||
go.mau.fi/whatsmeow v0.0.0-20221202110551-e067ee7293b0 h1:danzDOlj/KiDi8kNsaHOhwJ7IZdo7V7hXelkZXhJhsc= | ||
go.mau.fi/whatsmeow v0.0.0-20221202110551-e067ee7293b0/go.mod h1:2yweL8nczvtlIxkrvCb0y8xiO13rveX9lJPambwYV/E= | ||
golang.org/x/crypto v0.0.0-20221012134737-56aed061732a h1:NmSIgad6KjE6VvHciPZuNRTKxGhlPfD6OA87W/PLkqg= | ||
golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | ||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= | ||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= | ||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= | ||
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= | ||
rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
|
||
_ "github.com/mattn/go-sqlite3" | ||
"github.com/mdp/qrterminal/v3" | ||
"go.mau.fi/whatsmeow" | ||
waProto "go.mau.fi/whatsmeow/binary/proto" | ||
"go.mau.fi/whatsmeow/store/sqlstore" | ||
"go.mau.fi/whatsmeow/types" | ||
"go.mau.fi/whatsmeow/types/events" | ||
waLog "go.mau.fi/whatsmeow/util/log" | ||
"google.golang.org/protobuf/proto" | ||
) | ||
|
||
type MyClient struct { | ||
WAClient *whatsmeow.Client | ||
eventHandlerID uint32 | ||
} | ||
|
||
func (mycli *MyClient) register() { | ||
mycli.eventHandlerID = mycli.WAClient.AddEventHandler(mycli.eventHandler) | ||
} | ||
|
||
func (mycli *MyClient) eventHandler(evt interface{}) { | ||
switch v := evt.(type) { | ||
case *events.Message: | ||
newMessage := v.Message | ||
msg := newMessage.GetExtendedTextMessage().GetText() | ||
fmt.Println("Message received:", msg) | ||
// Make a http request to localhost:5001/chat?q= with the message, and send the response | ||
// URL encode the message | ||
urlEncoded := url.QueryEscape(msg) | ||
// Make the request | ||
resp, err := http.Get("http://localhost:5001/chat?q=" + urlEncoded) | ||
if err != nil { | ||
fmt.Println("Error making request:", err) | ||
return | ||
} | ||
// Read the response | ||
buf := new(bytes.Buffer) | ||
buf.ReadFrom(resp.Body) | ||
newMsg := buf.String() | ||
// encode out as a string | ||
response := &waProto.Message{Conversation: proto.String(string(newMsg))} | ||
userJid := types.NewJID(v.Info.Sender.User, types.DefaultUserServer) | ||
mycli.WAClient.SendMessage(context.Background(), userJid, "", response) | ||
|
||
} | ||
} | ||
|
||
func main() { | ||
dbLog := waLog.Stdout("Database", "DEBUG", true) | ||
// Make sure you add appropriate DB connector imports, e.g. github.com/mattn/go-sqlite3 for SQLite | ||
container, err := sqlstore.New("sqlite3", "file:examplestore.db?_foreign_keys=on", dbLog) | ||
if err != nil { | ||
panic(err) | ||
} | ||
// If you want multiple sessions, remember their JIDs and use .GetDevice(jid) or .GetAllDevices() instead. | ||
deviceStore, err := container.GetFirstDevice() | ||
if err != nil { | ||
panic(err) | ||
} | ||
clientLog := waLog.Stdout("Client", "DEBUG", true) | ||
client := whatsmeow.NewClient(deviceStore, clientLog) | ||
// add the eventHandler | ||
mycli := &MyClient{WAClient: client} | ||
mycli.register() | ||
|
||
if client.Store.ID == nil { | ||
// No ID stored, new login | ||
qrChan, _ := client.GetQRChannel(context.Background()) | ||
err = client.Connect() | ||
if err != nil { | ||
panic(err) | ||
} | ||
for evt := range qrChan { | ||
if evt.Event == "code" { | ||
// Render the QR code here | ||
// e.g. qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout) | ||
// or just manually `echo 2@... | qrencode -t ansiutf8` in a terminal | ||
qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout) | ||
// fmt.Println("QR code:", evt.Code) | ||
} else { | ||
fmt.Println("Login event:", evt.Event) | ||
} | ||
} | ||
} else { | ||
// Already logged in, just connect | ||
err = client.Connect() | ||
if err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
// Listen to Ctrl+C (you can also do something else that prevents the program from exiting) | ||
c := make(chan os.Signal) | ||
signal.Notify(c, os.Interrupt, syscall.SIGTERM) | ||
<-c | ||
|
||
client.Disconnect() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
"""Make some requests to OpenAI's chatbot""" | ||
|
||
import time | ||
import os | ||
import flask | ||
|
||
from flask import g | ||
|
||
from playwright.sync_api import sync_playwright | ||
|
||
APP = flask.Flask(__name__) | ||
PLAY = sync_playwright().start() | ||
BROWSER = PLAY.chromium.launch_persistent_context( | ||
user_data_dir="/tmp/playwright", | ||
headless=False, | ||
) | ||
PAGE = BROWSER.new_page() | ||
|
||
def get_input_box(): | ||
"""Get the child textarea of `PromptTextarea__TextareaWrapper`""" | ||
return PAGE.query_selector("div[class*='PromptTextarea__TextareaWrapper']").query_selector("textarea") | ||
|
||
def is_logged_in(): | ||
# See if we have a textarea with data-id="root" | ||
return get_input_box() is not None | ||
|
||
def send_message(message): | ||
# Send the message | ||
box = get_input_box() | ||
box.click() | ||
box.fill(message) | ||
box.press("Enter") | ||
|
||
def get_last_message(): | ||
"""Get the latest message""" | ||
page_elements = PAGE.query_selector_all("div[class*='ConversationItem__Message']") | ||
last_element = page_elements[-1] | ||
return last_element.inner_text() | ||
|
||
@APP.route("/chat", methods=["GET"]) | ||
def chat(): | ||
message = flask.request.args.get("q") | ||
print("Sending message: ", message) | ||
send_message(message) | ||
time.sleep(10) # TODO: there are about ten million ways to be smarter than this | ||
response = get_last_message() | ||
print("Response: ", response) | ||
return response | ||
|
||
def start_browser(): | ||
PAGE.goto("https://chat.openai.com/") | ||
if not is_logged_in(): | ||
print("Please log in to OpenAI Chat") | ||
print("Press enter when you're done") | ||
input() | ||
else: | ||
print("Logged in") | ||
APP.run(port=5001, threaded=False) | ||
|
||
if __name__ == "__main__": | ||
start_browser() |