đ©âđ« Tutoriels#
Dans cette page, nous essayons dâexpliquer comment rĂ©aliser un certain nombre dâactions avec notre librairie Python. IdĂ©alement, il vaut mieux la suivre Ă©tape par Ă©tape afin de suivre le cheminement, mais si vous vous sentez Ă lâaise, vous pouvez essayer dâaccĂ©der directement Ă la section qui vous intĂ©resse.
Les bases#
OlvidClient#
Pour interagir avec le daemon, il vous faudra systĂ©matiquement crĂ©er une instance de la classe OlvidClient. Il peut sâagir de la classe dâorigine ou dâune classe enfant.
Cette classe va automatiquement rĂ©cupĂ©rer une clĂ© client en utilisant lâenvironnement ou un fichier .env. (cf. Configuration)
Grùce à ce client, on pourra notamment exécuter des commandes et mettre en place des listeners de notifications.
Voici Ă quoi ressemble un fichier main.py de base contenant la crĂ©ation dâun client Olvid et lâexĂ©cution dâune commande (afficher lâidentitĂ© courante).
Cette structure est Ă utiliser dans chacun des exemples de code de cette page, il suffit de remplacer le contenu de la fonction main par le code de votre choix.
import asyncio
from olvid import OlvidClient, datatypes
async def main():
client = OlvidClient()
# code to replace
print(await client.identity_get())
asyncio.set_event_loop(asyncio.new_event_loop())
asyncio.get_event_loop().run_until_complete(main())
Commande#
Toutes les méthodes gRPC de commandes exposées par le daemon sont facilement accessibles grùce à des méthodes de la classe OlvidClient.
Par exemple, pour envoyer un message (mĂ©thode MessageSend en gRPC), on utilisera la mĂ©thode message_send de notre instance dâOlvidClient.
Dans le cas oĂč nous connaissons lâidentifiant de la discussion dans laquelle poster, cela donnerait :
from olvid import OlvidClient
client = OlvidClient()
client.message_send(discussion_id=1, body="Use Olvid !")
Notification#
La classe OlvidClient implémente également des méthodes qui permettent de facilement écouter les notifications émises par le daemon.
Ces mĂ©thodes commencent toutes par le prĂ©fixe on_ et doivent ĂȘtre redĂ©finies dans une classe fille dâOlvidClient.
Par exemple, pour afficher dans le terminal quand un message est reçu et lorsquâune rĂ©action est ajoutĂ©e, on peut faire :
import asyncio
from olvid import OlvidClient, datatypes
class Bot(OlvidClient):
async def on_message_received(self, message: datatypes.Message):
print(f"Message received: {message.body}")
async def on_message_reaction_added(self, message: datatypes.Message, reaction: datatypes.MessageReaction):
print(f"Reaction added: {reaction.reaction}")
async def main():
bot = Bot()
await bot.run_forever()
asyncio.set_event_loop(asyncio.new_event_loop())
asyncio.get_event_loop().run_until_complete(main())
Conseils et astuces#
AutoInvitationBot#
Pour rendre plus facile la mise en relation avec un bot, il est possible de mettre en place un autre bot, déjà écrit, qui acceptera toutes les invitations reçues.
Il suffit de crĂ©er un bot AutoInvitationBot du module olvid.tools. Il va automatiquement sâenregistrer pour recevoir les notifications de nouvelles invitations et les accepter.
Note
Un AutoInvitationBot ne peut accepter que les présentations et les invitations de groupe. Il ne peut pas accepter automatiquement les invitations directes avec échange de SAS code.
Voici un programme qui lance une instance de lâAutoInvitationBot en tĂąche de fond. Il est tout Ă fait possible de lancer plusieurs bots en parallĂšle.
import asyncio
from olvid import OlvidClient, datatypes, tools
class Bot(OlvidClient):
async def on_message_received(self, message: datatypes.Message):
print(f"Message received: {message.body}")
async def main():
bot = Bot()
tools.AutoInvitationBot()
await bot.run_forever()
asyncio.set_event_loop(asyncio.new_event_loop())
asyncio.get_event_loop().run_until_complete(main())
Divers#
Envoyer un message éphémÚre#
Les points dâentrĂ©e API messageSend et messageSendWithAttachments permettent de spĂ©cifier lâĂ©phĂ©mĂ©ralitĂ© du message Ă envoyer.
On utilisera pour cela lâobjet olvid.datatypes.MessageEphemerality.
Voici un exemple en python. Il est possible de spécifier les paramÚtres read_once, visibility_duration et existence_duration de maniÚre indépendante.
Les durĂ©es dâexistence et de visibilitĂ© sont en secondes.
import asyncio
from olvid import datatypes, OlvidClient
async def main():
client = OlvidClient()
async for discussion in client.discussion_list():
await client.message_send(
discussion_id=discussion.id,
body="Self-destruct message",
ephemerality=datatypes.MessageEphemerality(
visibility_duration=10,
existence_duration=60,
read_once=True
)
)
asyncio.run(main())
Utilisation avancée#
Listener#
Pour une implĂ©mentation plus fine de lâĂ©coute des notifications, il est possible dâutiliser la notion de Listener. Un listener est une souscription dâune fonction callback Ă un type de notification. Cette fonction sera appelĂ©e Ă chaque fois quâune notification de ce type est reçue.
Chaque type de notification a sa propre classe dans le module olvid.listeners.
Dans cet exemple, la mĂ©thode reply_to_message sera appelĂ©e Ă chaque fois quâun message arrive.
import asyncio
from olvid import OlvidClient, datatypes, listeners
async def reply_to_message(message: datatypes.Message):
await message.reply(f"Reply to: {message.body}")
async def main():
client = OlvidClient()
listener = listeners.MessageReceivedListener(handler=reply_to_message)
client.add_listener(listener)
await client.run_forever()
asyncio.set_event_loop(asyncio.new_event_loop())
asyncio.get_event_loop().run_until_complete(main())
Listener: expiration#
Par dĂ©faut, un listener Ă©coute les notifications pour toujours, mais il est possible dâutiliser lâargument count pour nâĂ©couter quâun certain nombre de notifications.
Dans ce cas, lorsque que count notifications ont Ă©tĂ© traitĂ©es, lâlistener est arrĂȘtĂ©.
Dans cet exemple, on rĂ©pond au prochain message reçu puis le programme sâarrĂȘte.
import asyncio
from olvid import OlvidClient, datatypes, listeners
async def reply_to_message(message: datatypes.Message):
await message.reply(f"Reply to: {message.body}")
async def main():
client = OlvidClient()
# added count parameter set to 1
listener = listeners.MessageReceivedListener(handler=reply_to_message, count=1)
client.add_listener(listener)
# wait_for_listeners_end: returns when all listeners are finished
await client.wait_for_listeners_end()
print("Program end")
asyncio.set_event_loop(asyncio.new_event_loop())
asyncio.get_event_loop().run_until_complete(main())
Listener : filtrage#
Les listeners permettent également de filtrer les notifications à traiter. Pour cela, on peut ajouter une ou plusieurs fonctions de filtrage à notre listener.
Par exemple, on peut vouloir traiter uniquement les messages envoyés par un contact donné.
import asyncio
from olvid import OlvidClient, datatypes, listeners
CONTACT_ID: int = 1
async def reply_to_message(message: datatypes.Message):
await message.reply(f"Reply to: {message.body}")
def check_sender_id(message: datatypes.Message):
return message.sender_id == CONTACT_ID
async def main():
client = OlvidClient()
# only notifications matching check_sender_id will be handled
listener = listeners.MessageReceivedListener(handler=reply_to_message, checkers=[check_sender_id])
client.add_listener(listener)
await client.wait_for_listeners_end()
asyncio.set_event_loop(asyncio.new_event_loop())
asyncio.get_event_loop().run_until_complete(main())
Listener avancé#
Il est tout Ă fait possible de combiner le filtrage et lâexpiration.
Ici, on lâutilise pour effectuer une action et quitter le programme quand le message que lâon vient dâenvoyer arrive sur le tĂ©lĂ©phone de son destinataire.
import asyncio
from olvid import OlvidClient, datatypes, listeners
DISCUSSION_ID: int = 1
def get_message_id_checker(message_id: datatypes.MessageId):
def checker(message: datatypes.Message):
return message.sender_id == message_id
return checker
async def main():
client = OlvidClient()
# send a message
message = await client.message_send(discussion_id=DISCUSSION_ID, body="Hello there !")
# add a listener to do something when message had been delivered, then program will exit
listener = listeners.MessageDeliveredListener(
handler=lambda m: print("Message delivered"),
checkers=[get_message_id_checker(message.id)],
count=1
)
client.add_listener(listener)
await client.wait_for_listeners_end()
print("Program end")
asyncio.set_event_loop(asyncio.new_event_loop())
asyncio.get_event_loop().run_until_complete(main())