from otree.api import * doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'simplechat' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): pass class ChatMessage(ExtraModel): group = models.Link(Group) round_number = models.IntegerField() sender = models.Link(Player) # None = system message text = models.LongStringField() timestamp = models.FloatField() # PAGES class MyPage(Page): pass from otree.api import * import time class ChatPage(Page): live_method = 'chat_handler' def js_vars(player): return dict( id_in_group=player.id_in_group, round_number=player.round_number ) def is_displayed(self): # Send one system message per round, from player 1 if self.id_in_group == 1: msg = f'🌀 Round {self.round_number} has started' ChatMessage.create( group=self.group, round_number=self.round_number, sender=None, text=msg, timestamp=time.time() ) for p in self.group.get_players(): p.send_live_update('chat_handler', dict( id_in_group='System', text=msg, timestamp=time.time() )) return True def live_chat_handler(player, data): ChatMessage.create( group=player.group, round_number=player.round_number, sender=player, text=data['text'], timestamp=time.time() ) for p in player.group.get_players(): p.send_live_update('chat_handler', dict( id_in_group=player.id_in_group, text=data['text'], timestamp=time.time() )) class ResultsWaitPage(WaitPage): pass class Results(Page): pass page_sequence = [MyPage, ChatPage]