Compare commits

..

10 commits

Author SHA1 Message Date
337cd46f24 EasyAppointments 2022-09-28 11:02:35 -04:00
a89dcede99 update readme 2022-08-09 15:44:19 -04:00
df587085e5 Update readme 2022-08-09 15:41:59 -04:00
9c717bd7a8 easyappointments mvp 2022-08-09 15:39:51 -04:00
ee0d8c579d Interactivity & storage overhaul complete.
Proof-of-concept adding and removing questions complete
2022-05-20 06:35:33 -04:00
6c71c30454 Revamp 2022-05-18 03:59:32 -04:00
2826163493 redundancies 2022-03-28 18:11:48 -04:00
4b67f4befb typo 2022-03-26 12:02:20 -04:00
02f451b41e spacing 2022-03-26 12:01:57 -04:00
459c0f58f9 docker instructions 2022-03-26 12:01:19 -04:00
11 changed files with 775 additions and 195 deletions

3
.gitignore vendored
View file

@ -1,3 +1,4 @@
data.json data.json
session.txt session.txt
__pycache__ __pycache__
easyappointments-flow.md

View file

@ -9,16 +9,23 @@
4. Create your own questions & answers and setup your keywords 4. Create your own questions & answers and setup your keywords
5. Run the bot `python main.py` 5. Run the bot `python main.py`
## details ## Docker container
1. `docker build -t matrix-nerve .`
2. `docker run -it matrix-nerve`
You may want to set data.json as a volume to be able to make changes on the fly
## Details
* The bot will listen to `!faq` and post the entire FAQ * The bot will listen to `!faq` and post the entire FAQ
* Based on selected keywords it will include relevant questions & answers ![Adding questions from matrix](screenshots/adding-questions.gif)
![matrix room screenshot](screenshots/example.png)
### Knock-knock jokes now supported! ## Features in the works
* Alerts
![matrix room screenshot](screenshots/example2.png) * Dynamic configuration
* Meeting requests (through easyappointments)
* Configurable API calls

View file

@ -1,153 +1,435 @@
import random import random
jokes = [ import features
["Testing","Testing you!"], import json
["singing pokemon","Jiggalypuff! 🎙️"]
]
#jokes = []
def handle_command(state,message): api = features.API()
debug = False
def handle_command(sender, message):
state = api.get_user_state(sender)
for command in commands: for command in commands:
if message.find(command)==0: if message.find(command) == 0:
result = commands[command](state,message) result = commands[command](state, message, sender)
return result return result
if len(state) > 0: if len(state) > 0:
if debug == 1:
return commands[state[0]](state, message, sender)
try: try:
result = commands[state[0]](state,message) result = commands[state[0]](state, message, sender)
return result return result
except Exception as e: except Exception as e:
if __name__ != '__main__':
state = []
api.update_user_state(sender, state)
return { return {
"state":[], "response": f"Error⚠\n{e}"
"response":f"Error⚠ \n {e}"
} }
return {
"response": "",
}
def get_faq_string():
return api.get_faq_string()
def nevermind(state, message, sender):
api.update_user_state(sender, [])
return {
"response": "starting over."
}
# faq
def get_faq(state, message, sender):
if len(state) == 0:
return {
"response": api.get_faq_string()
}
return {
"response": api.get_faq_string()
}
def add_question(state, message, sender):
if len(state) == 0:
api.update_user_state(sender, ["!add question"])
return {
'response': "Please enter the question title."
}
elif len(state) == 1:
state.append(message)
api.update_user_state(sender, state)
return {
'response': 'Please enter the answer to the question.'
}
elif len(state) == 2:
state.append(message)
api.update_user_state(sender, state)
state = api.get_user_state(sender)
return {
'response': f"Your question is:\n---\n# {state[1]}\n{state[2]}\n\n---\nIf this is what you want respond with `confirm`\n If you'd like to start over respond with `restart`\n Respond with `nevermind` to cancel entirely"
}
elif len(state) == 3:
if message == 'confirm':
api.add_question({
'question': state[1],
'answer': state[2]
})
api.update_user_state(sender, [])
return {
'response': 'Question added.'
}
elif message == 'restart':
api.update_user_state(sender, ['!add question'])
return {
'response': 'Please enter the question title.'
}
else:
return {
'response': f"Your question is:\n# {state[1]}\n{state[2]}\n\nIf this is what you want respond with `confirm`\n If you'd like to start over respond with `restart`\n Respond with `nevermind` to cancel entirely"
}
return {
'response': None
}
def update_question(state, message, sender):
if len(api.data['faq']['questions']) == 0:
api.update_user_state(sender, [])
return {
'response': "No questions registered."
}
elif len(state)==0:
api.update_user_state(sender,"!update question")
return {
"response":f"Choose a question to update:\n {api.get_faq_questions}"
}
return {
'response': None,
}
def remove_question(state, message, sender):
if len(api.data['faq']['questions']) == 0:
api.update_user_state(sender, [])
return {
'response': "No questions registered."
}
elif len(state)==0:
api.update_user_state(sender,["!remove question"])
return {
"response":f"Choose a question to remove:\n {api.get_faq_questions()}"
}
elif len(state) == 1:
try:
int(message)
except:
return {"response":"Please enter a number."}
state.append(message)
if int(state[1]) < len(api.data['faq']['questions']) and int(state[1]) >=0:
if debug == True:
api.remove_question(int(state[1]))
api.update_user_state(sender,[])
return {
'response':'Question removed'
}
else:
try:
api.update_user_state(sender,[])
api.remove_question(int(state[1]))
return {
'response':'Question removed'
}
except:
pass
api.update_user_state(sender,["!remove question"])
return {
'response':'Please enter the correct question #'
}
return { return {
"response":None, 'response': None,
"state":state
} }
"""
Knock-knock implimentation def update_header(state, message, sender):
when you receive message, read state.
user: knock knock
bot: who's there? -> bot responds and registers state
(user.state=[knock-knock])
user: {statement}
bot: {statement} who? -> bot responds and stores statement
(user.stage=[knock-knock,{statement}])
user: {punchline}
bot: Nice one! -> bot saves knock-knock joke
"""
def nevermind(state,message):
return { return {
"response":"starting over.", 'response': None,
"state":[]
} }
def knock_knock(state,message):
#return {response:"",state:""} def remove_header(state, message, sender):
try: return {
if state[0] != "knock knock": 'response': None,
#clear the state
state = [] }
except:
pass
if len(state) == 0: def update_footer(state, message, sender):
state.append("knock knock") return {
'response': None,
}
def remove_footer(state, message, sender):
return {
'response': None,
}
def add_admin(state, message, sender):
return {
'response': None,
}
def remove_admin(state, message, sender):
return {
'response': None,
}
def meetings(state,message,sender):
return {
'response':api.appointments.list_upcoming_appointments(sender)
}
def register_customer(state,message,sender):
if api.appointments.is_customer(sender):
return {'response':"Already registered."}
if state == ['!register2']:
return { return {
"response":"Who's there?", 'response':'What is your first name?'
"state": state }
if state == []:
state = ['!register']
api.update_user_state(sender, state)
return {
'response':'What is your first name?'
} }
if len(state) == 1: if len(state) == 1:
state.append(message) state.append(message)
api.update_user_state(sender, state)
return { return {
"response":message + " who?", 'response':'What is your last name?'
"state":state
} }
if len(state) == 2: if len(state) == 2:
state.append(message) state.append(message)
jokes.append([ api.update_user_state(sender, state)
state[1],state[2]
])
print("joke registered.")
return { return {
"response":"Hah! very funny!", 'response':'What is your e-mail?'
"state":[]
} }
if len(state) == 3:
return { state.append(message)
"response":"Cleared.", api.update_user_state(sender, state)
"state":[] return {
'response':"What is your phone number?"
}
if len(state) == 4:
state.append(message)
api.update_user_state(sender, state)
resp = f"You've entered: `{state[1]} {state[2]} ({state[3]} / {state[4]})`\n**Is this correct?**\nIf so, respond with:Yes\nIf not, to restart respond with :No\nYou can always cancel with:nevermind"
return {
'response':resp
}
if len(state) == 5:
if "yes" in message.lower():
data = {
"firstName":state[1],
"lastName":state[2],
"email":state[3],
"phone":state[4],
"notes":f"matrix:{sender}"
}
if sender == "admin":
dat = json.dumps(data)
print(f"Data:\n{dat}")
if api.appointments.register_customer(data):
if(state[0]=='!register2'):
state = ['!book']
api.update_user_state(sender, state)
return {'response':"Successfully registered.\n\n"+booking(['!book'],'',sender)['response']}
state = []
api.update_user_state(sender, state)
return{'response':"Successfully registered."}
else:
return{'response':"Error, please try again."}
api.update_user_state(sender, [])
return {
'response':''
} }
"""'joke' command def select_service(state,message,sender):
------------- if len(state) >= 2:
user:!joke return select_provider(state, message, sender)
bot:Knock knock -> bot initializes state # ['!book','select-service']
(user.state=[joke]) if message == "!book":
user: Who's there? return {'response':api.select_service()}
bot: {statement} -> bot responds with chosen joke else:
(user.state=[joke,chosenjoke]) try:
user: {statement} who? state.append(api.appointments.get_services()[int(message)]['id'])
bot: api.update_user_state(sender, state)
return booking(state, "", sender)
except:
return {'response':'Error selecting service\nTo cancel type:nevermind'}
def select_provider(state,message,sender):
if len(state) >= 3:
return select_time(state, message, sender)
if message == "":
return {'response':api.select_provider()}
try:
state.append(api.appointments.get_providers()[int(message)]['id'])
api.update_user_state(sender, state)
return booking(state,"",sender)
except:
return {'response':'Error selecting provider\nTo cancel type:nevermind'}
def select_time(state,message,sender):
if len(state) >= 5:
return booking(state, message, sender)
api.update_data()
# ['!book','select-time']
if len(state) == 3:
msg = api.select_times(state[1],state[2],message)
if msg == False:
return {'response':"Please enter a date you'd like to book (\"YYYY-MM-DD\" format)"}
state.append(message)
api.update_user_state(sender, state)
return {'response':msg}
if len(state) == 4:
times = api.appointments.get_availabilities(state[1], state[2], state[3])
if message in times:
state.append(message)
time = None
try:
time = times[int(message)-1]
state.append(time)
api.update_user_state(sender, state)
return booking(state, message, sender)
except:
return {'response':api.select_times(state[1],state[2],state[3])}
return {'response':error}
def booking(state,message,sender):
if len(state) > 5:
state = []
if state==[]:
state.append("!book")
api.update_user_state(sender, state)
""" """
def joke(state,message): To book an appointment, you need (in order):
if len(jokes) == 0: * the customer ID (now mapped to mxid) (0?)
return { * The service id (1)
"response":"I don't know any jokes...", * the provider id (2)
"state":[] * the start date & time (3)
} """
#Quick checks
customer = api.appointments.is_customer(sender)
if customer == False:
return register_customer([], "", sender)
#Service check
service = None
if len(api.appointments.services) == 0:
return {'response':"Error: there are no services"}
if len(api.appointments.services) == 1:
service = api.appointments.get_services()[0]
state.append(service)
api.update_user_state(sender, state)
return booking(state, message, sender)
if len(state) >= 2:
service = state[1]
if service == None:
return select_service(state, message, sender)
#Provider check
if len(state) == 0: provider = None
return { if len(api.appointments.providers) == 0:
"response":"Knock knock", return {'response':'error: there are no providers'}
"state":["joke"] if len(state) >= 3:
} provider = state[2]
elif len(state) == 1: elif len(api.appointments.providers) == 1:
if message.find("there?") > 0 : provider = api.appointments.get_providers()[0]['id']
#get random joke index if service != None:
state.append(random.randint(0,len(jokes)-1)) state.append(provider)
return { api.update_user_state(sender, state)
"response":jokes[state[1]][0], if provider == None:
"state":state return select_provider(state, message, sender)
}
else: time = None
return { if len(state) == 5:
"response":"ask, \"who's there?\"", time = state[4]
"state":state if time == None:
} return select_time(state, message, sender)
elif len(state) == 2: data = {
if message.find("who?") > 0: "start": state[3] + " "+ state[4]+":00",
return { "customerId":int(customer),
"response":jokes[state[1]][1], "providerId":int(provider),
"state":[] "serviceId":int(service)
} }
else: result = api.appointments.register_appointment(data)
return { if result != False:
"response":"ask, \""+ jokes[state[1]][0] +" who?\"", state = []
"state":state api.update_user_state(sender, state)
} return{'response':'Successfully registered appointment!'}
else:
return { state = []
"response":None, api.update_user_state(sender, state)
"state":[] print(result)
return{'response':"Error: please try again"}
return{'response':"Error: please try again"}
def services(state,message,sender):
return {
'response':api.list_services()
} }
commands = { commands = {
"nevermind":nevermind, "nevermind": nevermind,
"knock knock":knock_knock, "!faq": get_faq,
"joke":joke "!add question": add_question,
"!remove question": remove_question,
"!update question": update_question,
"!update header": update_header,
"!remove header": remove_header,
"!update footer": update_footer,
"!remove footer": remove_footer,
"!add admin": add_admin,
"!remove admin": remove_admin,
"!meetings":meetings,
"!register":register_customer,
"!register2":register_customer,
"!book":booking,
"!services":services
} }
if __name__ == '__main__': if __name__ == '__main__':
user = "admin"
msg = "" msg = ""
debug = True
while msg != "exit": while msg != "exit":
msg = input("user:") msg = input("user:")
user = handle_command(user,msg) print("bot:"+handle_command(user, msg)['response'])
#print("state:",user) # print("state:",user)

View file

@ -2,20 +2,24 @@
"username": "bot", "username": "bot",
"password": "hunter2", "password": "hunter2",
"homeserver": "http://localhost:8008", "homeserver": "http://localhost:8008",
"easyappointments": {
"token": "secrettoken",
"url": "http://localhost/easyappointments/index.php"
},
"faq": { "faq": {
"header": "# Simple example FAQ", "header": "# Simple example FAQ",
"questions": [{ "questions": [{
"question": "# What is the meaning of life?", "question": "What is the meaning of life?",
"answer": "42.", "answer": "42.",
"key_phrases": ["meaning", "life"] "key_phrases": ["meaning", "life"]
}, },
{ {
"question": "# Who is the coolest pokemon?", "question": "Who is the coolest pokemon?",
"answer": "Mewtwo! 🐈", "answer": "Mewtwo! 🐈",
"key_phrases": ["coolest", "pokemon"] "key_phrases": ["coolest", "pokemon"]
}, },
{ {
"question": "# What is the coolest programming language?", "question": "What is the coolest programming language?",
"answer": "🐍 python!", "answer": "🐍 python!",
"key_phrases": ["coolest", "programming", "language"] "key_phrases": ["coolest", "programming", "language"]
} }
@ -23,5 +27,7 @@
"footer": "Brought to you by Nerve\nSee the [code](https://codeberg.org/gabe/Nerve)" "footer": "Brought to you by Nerve\nSee the [code](https://codeberg.org/gabe/Nerve)"
}, },
"users": {} "users": {},
"admins": [],
"meetings": []
} }

151
easyappointments.py Normal file
View file

@ -0,0 +1,151 @@
import requests,json
class easyappointments:
def __init__(self,token,url):
self.token = token
self.url = url
self.headers = {"Authorization":f"Bearer {token}"}
self.appointments = {}
self.services = {}
self.providers = {}
self.customers = {}
try:
self.update_data()
except:
print("Failed to connect to easyappointments!")
def get_appointments(self):
data = requests.get(self.url+'/api/v1/appointments',headers=self.headers)
return data.json()
def get_services(self):
data = requests.get(self.url+'/api/v1/services',headers=self.headers)
return data.json()
def get_providers(self):
data = requests.get(self.url+'/api/v1/providers',headers=self.headers)
return data.json()
def get_customers(self):
data = requests.get(self.url+'/api/v1/customers',headers=self.headers)
return data.json()
def get_availabilities(self,service,provider,date):
try:
data = requests.get(self.url+f"/api/v1/availabilities?serviceId={service}&providerId={provider}&date={date}",headers=self.headers)
return data.json()
except:
return False
def update_data(self):
appointments = self.get_appointments()
for a in appointments:
self.appointments[a['id']] = a
services = self.get_services()
for s in services:
self.services[s['id']]=s
providers = self.get_providers()
for p in providers:
self.providers[p['id']]=p
customers = self.get_customers()
for c in customers:
self.customers[c['id']]=c
def is_customer(self,mxid):
customers = self.get_customers()
for c in customers:
if mxid in c['notes']:
return c['id']
return False
def is_provider(self,mxid):
providers = self.get_providers()
for p in providers:
if mxid in p['notes']:
return p['id']
return -1
def get_upcoming_appointments(self,mxid):
#get services & customers
id = self.is_provider(mxid)
if id:
apts = []
data = self.get_appointments()
for a in data:
if a['providerId'] == id:
apts.append(a)
return apts
else:
return []
def list_upcoming_appointments(self,mxid):
apts = self.get_upcoming_appointments(mxid)
if apts == []:
return "No meetings recorded."
output = ""
for a in apts:
service = self.services[a['serviceId']]['name']
customer = self.customers[a['customerId']]['firstName']
output += f"## {service} with {customer}\nTime:{a['start']}\n"
return output
def register_customer(self,customer_data):
#customer data
"""
{
"firstName":"name",
"lastName":"name",
"email":"email",
"phone":"phone"
"notes":"matrix:mxid"
}
"""
try:
id = requests.post(self.url+'/api/v1/customers',headers=self.headers,data=json.dumps(customer_data)).json()['id']
self.update_data()
return id
except:
return False
def register_appointment(self,appointment_data):
#appointment data
"""{
"start":"YY-MM-DD HH:MM:SS",
"customerId":9,
"providerId":4,
"serviceId:4
}
"""
print("Registering appointment:")
print(json.dumps(appointment_data))
result = requests.post(
self.url+'/api/v1/appointments',
headers = self.headers,
data=json.dumps(appointment_data)
)
id = result.json()['id']
if id:
return id
else:
return False
if __name__ == '__main__':
cdat = {
"firstName":"Test",
"lastName":"",
"email":"test@testing.xa",
"phone":"888-888-8888",
"notes":"matrix:@lol:testing"
}
adat = {
"start":"2022-09-28 09:00:00",
"customerId":8,
"providerId":4,
"serviceId":2
}
easy = easyappointments('secrettoken', 'http://localhost:8787/easyappointments/index.php')

1
error.log Normal file
View file

@ -0,0 +1 @@
Error:@gabriel:libresolutions.network: !bookError:@gabriel:libresolutions.network: !bookError:@gabriel:libresolutions.network: !register

0
faq.py
View file

188
features.py Normal file
View file

@ -0,0 +1,188 @@
import json
import requests
import easyappointments
import datetime
"""
Features
This is the main API for executing functions with data
"""
def check_date(date):
try:
datetime.datetime.strptime(date,"%Y-%m-%d")
except:
return False
return True
class API:
def __init__(self):
with open('data.json') as f:
self.data = json.loads(f.read())
self.appointments = easyappointments.easyappointments(self.data['easyappointments']['token'], self.data['easyappointments']['url'])
# Only refresh data when a change is made
def update_data(self):
with open('data.json','r') as f:
self.data = json.loads(f.read())
def save(self):
with open('data.json','w') as f:
f.write(json.dumps(self.data,indent=2))
return True
return False
#Administration
def is_admin(self,handle):
#return bool
pass
def add_admin(self,handle):
#return bool
if self.is_admin(handle):
return True
else:
self.data["admins"].append(handle)
self.save()
return True
def remove_admin(self,handle):
#return bool
if self.is_admin(handle):
i = self.data["admins"].index(handle)
self.data["admins"].pop(i)
self.save()
return True
else:
return True
#state management
def get_user_state(self,handle):
if handle not in self.data["users"]:
self.data["users"][handle]={"state":[]}
self.save()
return self.data["users"][handle]["state"]
def update_user_state(self,handle,state):
self.update_data()
current_state = self.get_user_state(handle)
self.data["users"][handle]["state"] = state
self.save()
return True
#FAQ
def get_faq_string(self):
faq = self.data["faq"]
return faq["header"] + "".join(
["\n# "+q["question"]+"\n"+q["answer"]+"\n" for q in faq["questions"]]
) + "\n"+ faq["footer"]
def get_faq_questions(self):
self.update_data()
questions = self.data['faq']['questions']
response = ""
index = 0
for question in questions:
response += f"[{index}]:{question['question']}\n"
index += 1
return response
def get_header(self):
self.update_data()
return self.data["faq"]["header"]
def set_header(self,hdr):
self.update_data()
#return bool
self.data["faq"]["header"] = hdr
self.save()
return True
def get_questions(self):
self.update_data()
#return questions
return self.data["faq"]["questions"]
def add_question(self,qtn):
self.update_data()
#return bool
self.data["faq"]["questions"].append(qtn)
self.save()
return True
def remove_question(self,qtn_i):
self.update_data()
#return bool
self.data["faq"]["questions"].pop(qtn_i)
self.save()
return True
def update_question(self,qtn_i,qtn):
self.update_data()
#return bool
self.data["faq"]["questions"][qtn_i]=qtn
return True
#Meetings
def get_meetings(self,mxid):
self.update_data()
self.appointments.list_upcoming_appointments(mxid)
pass
def list_services(self):
msg = "## Services:"
for i in self.appointments.services:
service = self.appointments.services[i]
name = service['name']
price = str(service['price']) + service['currency']
description = service['description']
msg += f"\n### {name}\nPrice:{price}\n{description}"
return msg
def select_service(self):
msg = "## Choose a service:"
counter = 1
for i in self.appointments.services:
service = self.appointments.services[i]
name = f"#{counter}: " + service['name']
price = str(service['price']) + service['currency']
description = service['description']
msg += f"\n### {name}\nPrice:{price}\n{description}"
counter += 1
msg += "\nPlease enter the # of the service:"
return msg
def select_provider(self):
msg = "## Choose a provider:"
counter = 1
for p in self.appointments.get_providers():
name = p['firstName']+" "+p['lastName']
msg += f"\n* #{counter}: {name}"
counter += 1
msg += "\nPlease enter the # of the provider"
return msg
def select_times(self,service,provider,date):
data = self.appointments.get_availabilities(service, provider, date)
if data == False or check_date(date) == False:
return False
msg = f"## Choose a time for {date}:\n"
counter = 1
for t in data:
msg += f"{counter}){t} "
counter +=1
msg +="\nPlease enter the # of time"
return msg
def request_meeting(self):
self.update_data()
pass
def accept_meeting(self):
self.update_data()
pass
if __name__ == '__main__':
api = API()
print("Storage loaded.\n",api.data['username'])

View file

@ -1 +0,0 @@
print("knock-knock functionality loaded")

87
main.py
View file

@ -4,87 +4,32 @@ import simplematrixbotlib as botlib
import commands import commands
data = json.loads(open('data.json').read()) data = json.loads(open('data.json').read())
dfaq = data["faq"]
userstate = data['users']
faq_text = dfaq["header"] + "".join(["\n"+q["question"]+"\n"+q["answer"]
for q in dfaq["questions"]]) + "\n\n"+dfaq["footer"]
creds = botlib.Creds( creds = botlib.Creds(
data["homeserver"], data["homeserver"],
data['username'], data['username'],
data['password'] data['password']
) )
bot = botlib.Bot(creds) bot = botlib.Bot(creds)
PREFIX = '!'
def load_faq():
dfaq = json.loads(open('data.json').read())["faq"]
return dfaq["header"] + "".join(["\n"+q["question"]+"\n"+q["answer"] for q in dfaq["questions"]]) + "\n\n"+dfaq["footer"]
def save_userstate():
with open('data.json','w') as f:
f.write(json.dumps(data,indent=4))
@bot.listener.on_message_event @bot.listener.on_message_event
async def faq(room, message): async def message(room, message):
if message.sender not in userstate: try:
userstate[message.sender] = {"state":[]} result = commands.handle_command(message.sender, message.body)
save_userstate() if result['response'] != None and result['response'] != "":
await bot.api.send_markdown_message(
room.room_id,
state = userstate[message.sender]['state'] result['response']
result = commands.handle_command(state,message.body) )
if result['response']!= None: except:
state = result['state'] with open("error.log",'a') as f:
userstate[message.sender]['state'] = result['state'] f.write(f"Error:{message}")
save_userstate()
await bot.api.send_markdown_message(
room.room_id,
result['response']
)
match = botlib.MessageMatch(room, message, bot, PREFIX)
#print(f"{message.sender} : {message.body}")
if match.is_not_from_this_bot() and match.prefix() and match.command(
"faq"):
await bot.api.send_markdown_message(
room.room_id,
load_faq())
@bot.listener.on_custom_event(nio.InviteMemberEvent) @bot.listener.on_custom_event(nio.InviteMemberEvent)
async def example(room, event): async def example(room, event):
if event.membership == "join": if event.membership == "join":
await bot.api.send_markdown_message( await bot.api.send_markdown_message(
room.room_id, room.room_id,
load_faq() commands.get_faq_string()
) )
def get_questions():
return json.loads(open('data.json').read())["faq"]["questions"]
@bot.listener.on_message_event
async def faqresponse(room, message):
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot():
response = ""
questions = get_questions()
for q in questions:
if sum([ 1 for kp in q["key_phrases"] if kp in message.body]) == len(q["key_phrases"]):
response += q["question"] + "\n" + q["answer"]+"\n"
if response != "":
await bot.api.send_markdown_message(
room.room_id,
response + dfaq["footer"]
)
bot.run() bot.run()

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB