Automatically add friends in twikoo comments

Posted by Biocide on Sun, 23 Jan 2022 15:24:56 +0100

In this article, you will see: Low technical power poor efficiency Almost no portability and scalability

The only advantage: for the novice (myself), it can be realized without mastering many technologies

demand

hexo's friend chain page is the same as the article. If you want to update it, you have to regenerate and deploy it After using webhook, Github Action or vercel to realize automatic deployment, it becomes more convenient to update website content: after local modification, it is directly pushed to the warehouse, and the rest is handed over to the server However, to add a friend chain, copy and paste it from the comment area to link YML and then push, it's still troublesome At present, there are ways to add friend chains through issue, but for lazy people like me, if I can do it in the comment area, I don't want to open another web page, so I want to make a little change to automatically obtain the friend chain information in the comment and add it directly (this is based on the premise of automatic deployment) I don't care about auditing. There aren't many comments now

thinking

The comments in my blog use twikoo. I can't see the code of cloud function (of course, I can't understand it), so there is only JS left. Simply look at F12 and find that after clicking the send button, twikoo all. JS will send a post request to the twikoo cloud function to request the request of the load_ The data field contains comment content, comment link, etc

Just in twikoo all. When JS sends a post request to the twikoo cloud function, it also sends a post request for comment content to my own server. The json format string parsed by the back end can extract the nickname, avatar, mailbox and website information required by the new friend chain, and then update the link in the warehouse through Github API YML file, then trigger webhook, and the server deploying the blog will automatically pull the latest code

Specific steps

Build a simple flash application

Flash is a lightweight web framework. The following is the simplest flash application. Accessing the URL in route() will trigger the following function, which will return an html code and the browser will render it

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

Start the application in the terminal and conduct local test, including flash_ hello in app = hello is the py file name

  • bash
  • cmd
  • powershell
export FLASK_APP=hello
flask run
set FLASK_APP=hello
flask run
$env:FLASK_APP = "hello"
flask run

The default port is 5000. Visit localhost:5000 to see Hello, World!

To process a post request, you just need to go to @ app Add methods=['post '] to the route decorator so that the route can only be accessed in post mode request.get_data can receive the payload of post requests

@app.route("/",methods=['post'])
def hello_world():
    print(request.get_data(as_text=True))
    

Click the send button and twikoo will launch a post request. The content of Request PayLoad is as follows:

As can be seen from the figure, you only need to parse the comment field

The comment field is html code, with the help of etree html parses text content from html code How to use JSON, XPath and subprocess tools will not be described here

Complete backend implementation:

The old version is obsolete

from flask import Flask
from flask import request
from markupsafe import escape
from lxml import etree
from flask_cors import *
import re
import time
import subprocess
import json

app = Flask(__name__)
CORS(app, supports_credentials=True) # Allow cross domain

@app.route("/",methods=['post'])
def hello_world():
    data = json.loads(request.get_data(as_text=True))
    data = json.loads(data['request_data'])
    # Check the source and replace it with your own
    if "comment" in data and data['href'] == 'https://www.bilibilianime.com/link/':
        with open('/var/hexo_source/hexo/source/_data/link.yml','a+')as f:
            # f.write(str(data))
            dom = etree.HTML(str(data['comment']))
            # f.write(s+'\n\n')
            info = []
            try:
                info = dom.xpath("//code[@class='language-yml']//text()")
                info =  [ainfo.strip() for ainfo in info[0].split("\n")]
                # f.write(str(info))
                template = "\n\n    {}\n      {}\n      {}\n      {}"    
                f.write(template.format(info[0],info[1],info[2],info[3]))
                with open('log.txt','a+')as logfile:
                    logfile.write(time.asctime( time.localtime(time.time()))+": Add a friend chain: "+" ".join(info)+"\n")
                # link.yml directory, change to your own
                subprocess.Popen('cd /var/hexo_source/hexo/&&git add .&&git commit -m "update: friend link"&&git push>log.txt',shell=True)
            except:
                with open('log.txt','a+')as logfile:
                    logfile.write(time.asctime( time.localtime(time.time()))+ ": Failed!"+"info: {}".format(" ".join(info))+"\n")
    
    else:
        return '<span>bad!</span>'
            
    return  '<span>ok!</span>'

Using Github API

from flask import Flask
from flask import request
from markupsafe import escape
from lxml import etree
from flask_cors import *
import re
import time
import subprocess
import json
import requests
import base64
import traceback


from twisted.internet import reactor
from twisted.web import proxy, server

# Fill in your token here
token = '' 

# Fill in your link here Github API link for YML
url = 'https://API.github.com/repos/ayasa520/hexo/contents/source/_data/link.yml' 
headers = {'Authorization': 'token ' + token}

app = Flask(__name__)

# Allow cross domain
CORS(app, supports_credentials=True) 




@app.route("/",methods=['post'])
def hello_world():
    data = json.loads(request.get_data(as_text=True))
    data = json.loads(data['request_data'])
    if "comment" in data and data['href'] == 'https://www.bilibilianime.com/link/':
        dom = etree.HTML(str(data['comment']))
        info = []
        try:
            info = dom.xpath("//code[@class='language-yml']//text()")
            info =  [ainfo.strip() for ainfo in info[0].split("\n")]
            template = "\n\n    {}\n      {}\n      {}\n      {}"    
            response_json = json.loads(requests.get(url, headers=headers).text)
            old_text = str(base64.b64decode(response_json['content']), encoding='utf-8')
            b64 = base64.b64encode((old_text +template.format(info[0],info[1],info[2],info[3])).encode('utf-8')).decode('ascii')
            data = {
                'message': "update from Python",
                'content': b64,
                'sha': response_json['sha']
            }            
            requests.put(url=url, data=json.dumps( data), headers=headers)
            with open('log.txt','a+')as logfile:
                logfile.write(time.asctime( time.localtime(time.time()))+": Add a friend chain: "+" ".join(info)+"\n")
        except  Exception as e:
            with open('log.txt','a+')as logfile:
                logfile.write(time.asctime( time.localtime(time.time()))+ ": Failed!"+"info: {}".format(" ".join(info))+"\n")
                logfile.write(traceback.format_exc())
    else:
        return '<span>bad</span>'
    return  '<span>ok!</span>'

In the non development environment, it is not appropriate to use the server provided by flash. Here I wrote a startup script and used Gunicorn as the server

source /var/hexo_source/simpleSever/# Flash source directory
gunicorn -w 2 -b :5000 flask_web:app # Bind to 5000 port flask_web py file name

Run the script to complete the deployment How to deploy to your own virtual machine is very detailed on the Internet, so I won't repeat it

stay https://postwoman.com.cn/ You can test quickly:

Change twikoo all. js

In the formatted twikoo all. Insert the following code at line JS 5783:

$.ajax({
    // This domain name points to port 5000. Replace it with your own
    url:'https://update-friend.bilibilianime.com/',
    type:'POST',
    dataType:'json',
    contentType:'application/json;charset=UTF-8',
    data:JSON.stringify(e.data),
    success:function(data, status){
        console.log(data);
    }
});

As shown in the figure:

Will theme_ config. Modify the CDN of twikoo in YML to the changed one All the work is finished

I didn't audit the friend chain, because there were not many critics, so I don't care about it now