神刀安全网

Periodic messages to your girlfriend on Messenger with PhantomJS

Imagine, if you will, that your girlfriend demands that you communicate with her more.

This does not make sense to you, since you see her in the morning as well every single evening.

"But Alice’s boyfriend texts her hearts and kisses during the day," she says.

"Ahh, alright," you reply and think that you can use cron but you will also need a script that can send messages as you to her on Facebook Messenger.

Messenger Platform

It looks like there is an official API for chat bots called the Messenger Platform .

But it appears that you need to create a new Facebook page for your bot but I need it to look like the messages come from me.

I can’t use this.

PhantomJS

If all you have is a hammer, everything looks like a nail.

In my last post, I wrote about using PhantomJS , a headless browser, to configure websites (like deactivating all plugins during a WordPress installation and then upgrading the blog to a network).

So my first thought was to try it for sending Messenger messages as well.

First, some ground work.

var system = require('system') var page = require('webpage').create()  var email = system.args[1] var pass = system.args[2] var conversation = system.args[3] var text = system.args[4]  var steps = [] // array of functions 

You will need to provide your email as well as your password to log in.

conversation is the conversation (or thread) ID that you can see in the URL in your browser (e.g. https://www.messenger.com/t/firstname.lastname ). It is usually firstname.lastname or sometimes john.smith.99 .

Let’s go to messenger.com

function() {   console.log('Opening messenger.com')   page.open('https://www.messenger.com/') } 

and log in

function() {   console.log('Logging in')   page.evaluate(function(email, pass) {     document.querySelector('input[name=email]').value = email     document.querySelector('input[name=pass]').value = pass     document.querySelector('#loginbutton').click()   }, email, pass) }, 

What I did was right click on the input fields in Google Chrome, click Inspect and look at the <input> elements for email and password.

Then I fill them out programmatically with JavaScript.

I can verify that it works by copy & pasting the document.querySelector code lines in the Google Chrome console.

If I can do that in the Google Chrome console, I can do that in PhantomJS as well.

Everything in page.evaluate(function() { ... }) is executed on the currently open web page. Since email and pass are my variables, they do not exist on messenger.com so I need to pass them as parameters. You can also return a value from page.evaluate .

Next, go to the conversation with the girlfriend.

function() {   page.open('https://www.messenger.com/t/' + conversation) },  function() {   console.log('Talking to', page.evaluate(function() {     return document.querySelector('div[role="main"] h2').innerText   })) } 

Finally, send the message.

function() {   text.split('/n').forEach(function(line) {     page.sendEvent('keypress', line)     page.sendEvent('keypress', page.event.key.Enter, null, null, 0x02000000 /* shift */)   })   page.sendEvent('keypress', page.event.key.Enter) } 

I could not figure out how to fake the keyup or paste event (messenger.com uses React and a custom component instead of an <input> ). But the input text box is focused when you open the page and I can just simulate the key presses.

There is no /n key so I need to press Shift + Enter to start a new line with the keyboard.

Here is the whole script with some code at the end to execute the array of functions.

var system = require('system') var page = require('webpage').create()  var email = system.args[1] var pass = system.args[2] var conversation = system.args[3] var text = system.args[4]  var steps = [   function() {     console.log('Opening messenger.com')     page.open('https://www.messenger.com/')   },   function() {     console.log('Logging in')     page.evaluate(function(email, pass) {       document.querySelector('input[name=email]').value = email       document.querySelector('input[name=pass]').value = pass       document.querySelector('#loginbutton').click()     }, email, pass)   },   function() {     console.log(page.evaluate(function() {       return document.querySelector('div[role="banner"] a[href="/new"]')         ? "Logged in" : "Could not log in"     }))   },   function() {     page.open('https://www.messenger.com/t/' + conversation)   },   function() {     console.log('Talking to', page.evaluate(function() {       return document.querySelector('div[role="main"] h2').innerText     }))   },   function() {     text.split('/n').forEach(function(line) {       page.sendEvent('keypress', line)       page.sendEvent('keypress', page.event.key.Enter, null, null, 0x02000000 /* shift */)     })     page.sendEvent('keypress', page.event.key.Enter)   },   function() {     page.evaluate(function() {       console.log('Done')     })   },   function() {     setTimeout(function() { phantom.exit() }, 2000)   } ]  var stepindex = 0 var loading = false setInterval(executeRequestsStepByStep, 50)  function executeRequestsStepByStep() {   if (loading == false && steps[stepindex]) {     steps[stepindex]()     stepindex++   } }  page.onLoadStarted = function() { loading = true } page.onLoadFinished = function() { loading = false } page.onConsoleMessage = function(msg) { console.log(msg) } 

Run it

$ phantomjs messenger.js your@email.com password conversation.name "your message here" Opening messenger.com Logging in Logged in Talking to Your Girlfriend Done 

If you don’t have PhantomJS installed already, this will download and extract a static binary phantomjs to /usr/local/bin .

curl -L https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 | /   sudo tar xj -C /usr/local/bin phantomjs-2.1.1-linux-x86_64/bin/phantomjs --strip-components 2 

PhantomJS also works on Windows.

facebook-chat-api

But there’s more than one way to skin a cat.

Another way would be to write a script that makes the same HTTP requests that the Messenger client does.

But I had a suspicion that there would be a node.js module for this already. Let’s try to use facebook-chat-api .

npm install facebook-chat-api 

The script

var login = require('facebook-chat-api')  var email = process.argv[2] var pass = process.argv[3] var conversation = process.argv[4] var text = process.argv[5]  login({ email: email, password: pass}, (err, api) => {   if (err) throw err    api.getFriendsList((err, profiles) => {     if (err) throw err      var friendProfile = profiles.filter(p => p.vanity == conversation)[0]     if (friendProfile) {       api.sendMessage({ body: text }, friendProfile.userID)     } else {       throw 'Friend not found'     }   }) }) 

Run it

$ node fchat.js your@email.com password conversation.name "your message here" info Logging in... info Logged in info Request to reconnect info Request to pull 1 info Request to pull 2 info Request to thread_sync info Done logging in. 

Creating an echo bot is just as simple.

This example is taken from the docs. I modified it for brevity.

var login = require('facebook-chat-api')  var email = process.argv[2] var pass = process.argv[3]  login({ email: email, password: pass }, (err, api) => {   if (err) throw err    api.listen((err, event, stopListening) => {     if (err) return console.error(err)      if (event.type === 'message') {       api.sendMessage(event.body, event.threadID)     }   }) }) 

Final remarks

I should point out that doing this is probably against the Terms of Service.

Nevertheless, it was fun playing with PhantomJS.

While the facebook-chat-api code is much shorter and there are other people maintaining the underlying code, if I had to write a quick one-off script like this, I would probably use PhantomJS since it took me very little time to script what I did in the browser.

Just remember that you should not use this script to propose to your girlfriend or anything like that.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Periodic messages to your girlfriend on Messenger with PhantomJS

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址