preface
Demand is introduced
Recently had a friend sea-front see nana meters seven seas live every day, as a friend of me was to see not bottom go to, in line with the idle fun to play than attitude suddenly wants to notice the whole a QQ robot dynamic, haizi elder sister live a premiere is pushed to the news group, convenient friends online charge a gift in a timely manner
In this paper, characteristics of
This article is mainly used to briefly introduce the construction of QQ robot, so everything is simple, mainly about the basic principles and implementation functions, if you want to further understand please read the official document
The article is targeted at groups: zero-based groups, patients who do not want to read official documents, togele readers, and crisp sharks
If you are part of the audience, get started!!
Environment to prepare
Knock on the code
There are two main things you need to type code:
- Node: code environment
- Vscode: code editor
The code used this time is based on node environment development, so you must install node environment, node download address
Of course, if you don’t want to use the universe super easy to use vscode to knock code, with notepad is not impossible, vscode download address
After downloading the Node environment, enter NPM on the terminal with the following information (or success as long as the command is not found)
If you have any questions, see: How do I Configure the Node Environment
Access to the QQ
Note: QQ robot is the risk of risk control, so do not use your own QQ as a robot, please register a new trumpet
First of all we need a tool to login QQ, this tool can get all the chat information on our QQ, and can output these information to other places, and even control our QQ to send specified information, so where there is so good tool??
This has to say the famous GO-CQHTTP, using it can be very convenient to access QQ and open data communication services, can be understood as we logged in a QQ without an operation interface
First of all, we need to download, download the address, please choose the download package according to your own operating system, if access failure, please scientific Internet access
In the following example, I take Windows as an example. After downloading the application, the terminal may prompt you which service you need to connect to. You can choose multiple services here, but select 2 to select forward WebSocket service, which will automatically generate the default configuration file config.yml in the current directory
If you are a MAC user, the generated configuration file will be placed in the user’s home directory
The following is a brief introduction to the configuration information: First, you need to fill in the login information, here only need to fill in the QQ number and password (here to 123456 as an example), start the application again can realize the login QQ
# config.yml
account: # Account related
uin: 123456 # QQ account
password: '123456' If the password is empty, use scan to log in
encrypt: false # Whether to enable password encryption
status: 0 # online status Please refer to the https://docs.go-cqhttp.org/guide/config.html# online status
relogin: # reconnection Settings
delay: 3 # First reconnect delay, in seconds
interval: 3 Reconnection interval
max-times: 0 # Maximum number of reconnections, 0 is unlimited
# Whether to use the new address delivered by the server for reconnection
Note that this setting may result in worse connections on overseas servers
use-sso-address: true
Copy the code
Remember the address of the enabled Websocket service, which indicates that the local machine will serve as the server and the service port is 6700
# Connect service list
servers:
- ws:
# forward WS server listening address
host: 127.0. 01.
# forward WS server listening port
port: 6700
middlewares:
< < : *default # reference default middleware
Copy the code
In fact, you can input an account and password to act as a robot, and the other configuration is not changed by default. If you are interested, you can check the official configuration information. The principle of this article is: It works
If the startup is successful, the following information is displayed
At this time, if you use the QQ to speak or receive messages, you will see in the terminal. Yes, the GO-CQHTTP service can monitor all the behavior of the user
Note: Please keep the service open and do not close the terminal
Operating robot
We have been able to log in QQ to get user behavior information, so now we also need to use a thing to control our QQ user to do something we want to do, that is, to turn it into a robot
There are quite a few mature chatbot frameworks out there, and THIS time I chose Koishi for the following reasons:
- There are a lot of mature community plugins, you can use directly, can not write code to write code, switch man ecstasy
- Use JS language to write code, cut diagram son ecstasy
Start by creating a new directory, which I will call Koishi -robot. Open the directory path terminal and type in sequence (please make sure you have installed the Node environment before).
npm init -y
npm install koishi koishi-adapter-onebot koishi-plugin-common
Copy the code
First of all, we need to configure QQ information and service information, create a file config.js under the koishi- Robot folder and enter it
// koishi-robot/config.js
module.exports = {
// Koishi server listens to the port
port: 8080.onebot: {
path: ' '.secret: ' ',},bots: [{
type: 'onebot:ws'.server: 'http://localhost:6700'.selfId: 'Fill in the QQ number here'.token: 'Fill in the QQ password here',}],plugins: {
'common': {}}}Copy the code
Note: The server must be the same as the go-CqHTTP enabled service address. It can be seen that the configuration information of the server above is the go-CqHTTP address and port
Now you need to generate the robot control service, create a new file app.js under the koishi- Robot folder and enter it
// koishi-robot/app.js
const { App } = require('koishi')
const config = require('./koishi.config')
require('koishi-adapter-onebot')
// Inject the configuration
const app = newApp({ ... config })// Register the plug-in
app.plugin(require('koishi-plugin-common'))
app.start()
Copy the code
Here is the terminal input in the Koishi – Robot path to start our service
node app.js
Copy the code
If successful, the following information is displayed:
At this point we have successfully started the service to control the QQ robot. The koishi-plugin-common plug-in introduced just now has some basic functions built in. You can try to use the echo command to make our robot reply to specified messages
Thus, we have basically created a QQ robot that can be easily understood using the following model
Write a function
The plug-in
Koishi mainly controls our robot behavior in the form of plug-ins, writing a set of logic and then configuring it to use in the service
First of all, for the convenience of development and debugging, we will first install a Nodemon package to enable our service to achieve hot update: that is, to modify the code to update the service immediately without manual restart, and to enter the project path terminal
npm install nodemon
Copy the code
Then modify the package.json in our directory to add the project startup command. At this time, the content of my file is:
{
"name": "koishi-robot"."version": "1.0.0"."main": "index.js"."license": "MIT"."scripts": {
"start": "nodemon ./src/app.js"
},
"dependencies": {
"koishi": "^ 3.14.2"."koishi-adapter-onebot": "^ 3.1.0"."koishi-plugin-common": "^ 4.3.5." "."nodemon": "^ 2.0.13"}}Copy the code
Next try to start the service, enter the project path terminal
npm run start
Copy the code
The following is a brief introduction to the writing of the plug-in. In the project directory, create a new file plugin.js
// koishi-robot/plugin.js
function apply(ctx) {}module.exports = {
name: 'plugin-my-plugin',
apply
}
Copy the code
You then need to reference the plug-in in the service
// index.js
/ /... Other code
app.plugin(require('./plugin'))
Copy the code
Finally, configure it in the configuration file. (Here, you can use it if you don’t like it, but you should still be in awe of the official document.)
The path to the plugin with a key name, such as.plugin here, corresponds to our plugin.js file
// koishi-robot/config.js
module.exports = {
/ /... Other configuration
plugins: {
'./plugin': true.// true is equivalent to {}}},Copy the code
Now that we have imported the plug-in, we can write functions for the plug-in. First, we will introduce how to write the middleware
// koishi-robot/plugin.js
function apply(ctx) {
ctx.middleware((session, next) = > {
// Here is what the robot should do after receiving the message
return next()
})
}
Copy the code
Any message received by the robot will trigger the middleware. We can set here what the robot should do after receiving any message. We can first take a look at what data we get after receiving the message
In order to make the performance more vivid, we don’t mind exposing two small messages of our own. Here are the session information obtained by using 850300443 as the carrier of the robot and 2536671541 as the speaker of the trigger robot
It can be seen that the following main information can be easily obtained at this time:
- Spokesperson information, such as QQ number, nickname, etc
- QQ group information, such as QQ group number
- Chat content, such as text and picture messages, channel (private chat or group chat) and sending time, etc
For example, we could easily write out a feature where a bot sends a message when it finds a specific user in a group
function apply(ctx) {
ctx.middleware((session, next) = > {
// If the user whose QQ id is 2536671541 is detected to speak, send the specified statement
if(session.userId === '2536671541') {
session.send('Listen to the specified user')}return next()
})
}
Copy the code
Session.send () is used to send the specified content to the corresponding channel after the robot receives the message, that is, it will reply to the corresponding group or private chat after the message is monitored. Generally, it needs to add a judgment statement, otherwise any speech (no matter what channel) will be replied
instruction
Sometimes, we want to be able to trigger the robot’s actions with commands, such as the original Echo operation, which requires commands
function apply(ctx) {
ctx
.command('live'.'Query The broadcast Status of Sister Hai Zi')
.shortcut("Haizi Sister on the air?")
.action(({ session }) = > {
session.send("Got the order? Is Haizi on the air?")})}Copy the code
Description shortcut: command alias which can be used to trigger the command Action: the operation to be done after receiving the command
radio
Now that we know that the machine will send the message only after receiving the message, what is the method that can directly control the robot to send the message to the designated channel? The following is the basic writing method of broadcast
function apply(ctx) {
ctx.broadcast(
['onebot:private:123456'.'onebot:group:654321'].'Sent message')}Copy the code
The above code functions: Manually send the message “sent message” to qq 123456 and QQ group 654321. Onbot refers to a platform, because Koishi can access not only QQ but also other platforms. Onebot refers to QQ platform
News section
Sometimes we hope that the robot can not only make ordinary speeches, but also use message segments to enrich the behavior of the robot. Its principle is to use CQcode to let QQ know the operation of a user. Since go-CQHTTP is used to access QQ, the message segment in Koishi is completely corresponding to the framework. CQcode reference
For example, if we want the robot to poke someone, we could write this
const { segment } = require('koishi')
function apply(ctx) {
ctx
.command('live'.'Query The broadcast Status of Sister Hai Zi')
.shortcut("Haizi Sister on the air?")
.action(({ session }) = > {
return segment('poke', {qq: 123456})})}Copy the code
SQL > select segment 123456 from ‘CQcode’
Formally started
Broadcast room information
The basic functions are almost finished, and there are more than the following side to write while introducing it, in fact, according to the above knowledge, at this Time you should almost be able to create a robot function you want, the following began to enter the formal construction link, to create a direct formal entry into the haizi sister live notification robot Time
The following writing method is mainly copied from the community plug-in writing method: Koishi-plugin-blive, a plug-in for b station live
The basic principle is very simple, Hai Zi elder sister live in B station, then request b station live related interface, get hai Zi elder sister live room information
First of all, according to the mysterious power, we got the request interface of the direct broadcast room of station B, and the requested content and returned content are shown in the figure:
-
The id value after the requested address is the room number of station B, for example, the room number of Sister Hai Zi is 21452505
-
The returned content can get the relevant information of the live broadcast room. Here we mainly focus on the live_status field, and the meaning of the value is as follows
- 0: not aired
- 1: Live
- 2: in rotation
And then we need to actively request this interface in our code, so I’m going to send the requestaxios
Package, so you need to download it in the project
npm install axios
Copy the code
Then in our plug-in to use, here in line with the principle of all simple, not the code to write elegant and consider reuse packaging, all for haizi sister service!!
const axios = require('axios')
async function apply(ctx) {
const { data } = await axios.get(
'https://api.live.bilibili.com/room/v1/Room/room_init',
{
params: { id: 21452505 },
headers: {
'User-Agent':'the Mozilla / 5.0 (Windows NT 10.0; Win64; x64; The rv: 88.0) Gecko / 20100101 Firefox 88.0 / '}})const liveStatus = {
'0': 'Not on air'.'1': 'Live'.'2': 'In rotation'
}[data.live_status]
ctx.broadcast(
['onebot:group:123456'].'Sister Hai Zi's live status:${liveStatus}`)}Copy the code
The function of the above code: request to obtain the status of haizi sister broadcast, send information to qq group 123456
Loop request
What we need is to get the information immediately as soon as Sister Haizi starts broadcasting. The above code obviously does not meet the requirements. Therefore, what we need is to request the interface every minute and only push the message to the group when the status of sister Haizi’s live broadcast changes
const axios = require('axios')
let preStatus = 0 // Stores the status of the last request
let statusSwitch = false // Used to store whether the state of the broadcast room has changed since the last request
function apply(ctx) {
// The following code is triggered when Koishi accesses the GO-CQHTTP service
ctx.on('connect'.() = > {
setInterval(async() = > {const { data } = await axios.get(
'https://api.live.bilibili.com/room/v1/Room/room_init',
{
params: { id: 21452505 },
headers: {
'User-Agent':'the Mozilla / 5.0 (Windows NT 10.0; Win64; x64; The rv: 88.0) Gecko / 20100101 Firefox 88.0 / '}})if(preStatus ! == data.live_status) { statusSwitch =true
preStatus = data.live_status
} else {
statusSwitch = false
}
// If the live stream status changes, send messages to the designated QQ group
if(statusSwitch) {
const message = preStatus ? 'Sister Haizi is playing it.' : 'Hai Zi Jie is on the air'
ctx.broadcast(
['onebot:group:123456'],
message
)
}
}, 60 * 1000) // Repeat for 60 seconds})}Copy the code
The function of the above code is: request the live broadcast information once every minute, once the live broadcast status changes, send push message to the QQ group, pay attention to the repetition time is not too short, do not high-frequency request interface may be limited by B station request (do not ask me how to know)
QQxml
Note: XML is a black technology, sending qq number many times will lead to risk control, resulting in the normal sending OF XML, here is just a brief introduction, the specific implementation can be used to try new small (the author has been risk control 4 small in order to debug the code
Now we have a simple live push robot haizi Sister to complete the function, but there are still some shortcomings in the speech, only to send a text is not elegant, so we introduced QQxml to realize the function of sending QQ cards
Koishi can send a piece of XML code through QQcode, which is parsed internally by QQ and turned into a specific message effect, such as QQ’s card information
Since I don’t know much about risk, I’ll just take a look at the two templates and effects of XML. XML code requires a special header declaration, as shown below
Copy the code
QQ cards use the < MSG >
tag to wrap content
<msg serviceID="1" templateID="1" action="web" brief="Click to go to the studio." sourceMsgId="0" url="https://live.bilibili.com/21452505?spm_id_from=333.999.0.0" flag="0" adverSign="0" multiMsgFlag="0">
<! -- Card content -->
</msg>
Copy the code
Brief: Preview information seen outside the chat box URL: Click the card to jump to the other unknown what effect ~
The following are the templates for two XML cards that were tried out, while other configuration attempts were somewhat problematic
<msg serviceID="1" templateID="1" action="web" brief="Click to go to the studio." sourceMsgId="0" url="https://live.bilibili.com/21452505?spm_id_from=333.999.0.0" flag="0" adverSign="0" multiMsgFlag="0">
<item layout="6" advertiser_id="0" aid="0">
<picture cover="http://gchat.qpic.cn/gchatpic_new/0/530077417-0-094758B3DD39603D0E8563D47959D8E7/0" w="0" h="0" />
</item>
<item layout="6" advertiser_id="0" aid="0">
<title>Sister Haizi live broadcast room</title>
<summary>${liveStatus}${liveStartTime}${liveTime}</summary>
</item>
<source name="Billie Billie" icon="http://gchat.qpic.cn/gchatpic_new/0/530077417-0-01006648643525F8630A9A97C5959700/0" action="" appid="1" />
</msg>
Copy the code
<msg serviceID="1" templateID="1" action="web" brief="Click to go to the studio." sourceMsgId="0" url="https://live.bilibili.com/21452505?spm_id_from=333.999.0.0" flag="0" adverSign="0" multiMsgFlag="0">
<item layout="2" advertiser_id="0" aid="0">
<picture cover="http://gchat.qpic.cn/gchatpic_new/0/530077417-0-094758B3DD39603D0E8563D47959D8E7/0" w="0" h="0" />
<title>Sister Haizi live broadcast room</title>
<summary>${liveStatus}${liveStartTime}${liveTime}</summary>
</item>
<source name="Billie Billie" icon="http://gchat.qpic.cn/gchatpic_new/0/530077417-0-01006648643525F8630A9A97C5959700/0" action="" appid="1" />
</msg>
Copy the code
By contrast, you have noticed that the picture address here is not the address of any picture on the network. This is the picture bed inside QQ. Pictures directly used on the Network can be normally displayed in the card on the mobile phone, but will be cracked on the PC
This is because THE PC card reference is QQ’s own map in the bed, if you really want to normal display on the PC can be operated as follows:
- Manually get the MD5 value of a downloaded image (all uppercase)
- Use QQ to send a message
http://gchat.qpic.cn/gchatpic_new/0/530077417-0- < fill in this md5 value, do not need Angle brackets > / 0
, this step is equivalent to the picture saved to QQ inside - B station detailed tutorial
Afterword.
So far we’ve implemented all the features we want, and I’m sure you don’t have to be a crunchy shark to figure out how to make a robot you want
There is a problem that is now we are using the computer ACTS as a server, it means that we want our robot work will have to open the computer all day, this is not realistic, so we need to buy a server, then put our project to the server, and run on the server
The choice of the server has a lot of, such as Ali cloud, Tencent cloud, if you have been determined to spend money to get the server, then I believe you can go to Baidu search out how to buy a server and deployment project, here is not introduced