这份文档还在翻译中,预期年底前完成。欢迎您提供宝贵的意见及建议。

Using more Events with the Nexmo Client SDK

In this guide we'll cover adding more conversation events; we'll deal with multiple types of events, the ones that come via the conversation, and the ones we send to the conversation.

Concepts

This guide will introduce you to the following concepts.

  • Conversation Events - member:left and text: events that fire on a Conversation when someone does an Action
  • Conversation Actions - actions that trigger events on a Conversation
  • Conversation History - an events object that stores all text Events happening on a conversation

NOTE: A step-by-step tutorial to build a chat application is available here.

The getEvents method retrieves all the events that occurred in the context of the conversation. It returns a subset or "page" of events with each invocation - the number of events it returns is based on the page_size parameter (the default is 10 results, the maximum is 100).

Note: See the documentation for helper methods you can use to work with this paginated data.

conversation
  .getEvents({ page_size: 20 })
  .then((events_page) => {
    events_page.items.forEach((value, key) => {
      if (conversation.members.get(value.from)) {
        const date = new Date(Date.parse(value.timestamp))

        switch (value.type) {

          case 'member:joined':
            console.log(`${conversation.members.get(value.from).user.name} @ ${date}: joined the conversation`);
            break;
          case 'member:left':
            console.log(`${conversation.members.get(value.from).user.name} @ ${date}: left the conversation`);
            break;
          case 'member:invited':
            console.log(`${conversation.members.get(value.from).user.name} @ ${date}: invited to the conversation`);
            break;

          case 'text:seen':
            console.log(`${conversation.members.get(value.from).user.name} saw text at @ ${date} : ${value.body.text}`))
            break;
          case 'text:delivered':
            console.log(`Text from ${conversation.members.get(value.from).user.name} delivered at @ ${date} : ${value.body.text}`))
            break;
          case 'text':
            console.log(`${conversation.members.get(value.from).user.name} @ ${date}: ${value.body.text}`);
            break;

          case 'text:typing:on':
            console.log(`${conversation.members.get(value.from).user.name} starting typing @ ${date}`);
            break;
          case 'text:typing:off':
            console.log(`${conversation.members.get(value.from).user.name} stopped typing @ ${date}`);
            break;

          default:
            console.log(`${conversation.members.get(value.from).user.name} @ ${date}: unknown event`);
        }
      }
    })

  })
  .catch(this.errorLogger)

private fun getConversationEvents(conversation: NexmoConversation) {
    conversation.getEvents(100, NexmoPageOrder.NexmoMPageOrderAsc, null,
        object : NexmoRequestListener<NexmoEventsPage> {
            override fun onSuccess(nexmoEventsPage: NexmoEventsPage?) {
                nexmoEventsPage?.pageResponse?.data?.let {
                    processEvents(it.toList())
                }
            }

            override fun onError(apiError: NexmoApiError) {
                Log.d("TAG", "Error: Unable to load conversation events ${apiError.message}")
            }
        })
}

private fun processEvents(events: List<NexmoEvent>) {
    events.forEach {
        val message = when (it) {
            is NexmoMemberEvent -> getEventText(it)
            is NexmoTextEvent -> getEventText(it)
            is NexmoSeenEvent -> getEventText(it)
            is NexmoDeliveredEvent -> getEventText(it)
            is NexmoTypingEvent -> getEventText(it)
            else -> "Unsupported event ${it.eventType}"
        }

        Log.d("TAG", message)
    }
}

private fun getEventText(typingEvent: NexmoTypingEvent): String {
    val user = typingEvent.fromMember.user.name
    val typingState = if (typingEvent.state == NexmoTypingState.ON) "typing" else "not typing"
    return "$user is $typingState"
}

private fun getEventText(deliveredEvent: NexmoDeliveredEvent): String {
    val user = deliveredEvent.fromMember.user.name
    return "Event from $user with id ${deliveredEvent.initialEventId()} delivered at ${deliveredEvent.creationDate}"
}

private fun getEventText(seenEvent: NexmoSeenEvent): String {
    val user = seenEvent.fromMember.user.name
    return "$user saw event with id ${seenEvent.initialEventId()} at ${seenEvent.creationDate}"
}

private fun getEventText(textEvent: NexmoTextEvent): String {
    val user = textEvent.fromMember.user.name
    return "$user said: ${textEvent.text}"
}

private fun getEventText(memberEvent: NexmoMemberEvent): String {
    val user = memberEvent.member.user.name

    return when (memberEvent.state) {
        NexmoMemberState.JOINED -> "$user joined"
        NexmoMemberState.INVITED -> "$user invited"
        NexmoMemberState.LEFT -> "$user left"
        else -> "Error: Unknown member event state"
    }
}
private void getConversationEvents(NexmoConversation conversation) {
    conversation.getEvents(100, NexmoPageOrder.NexmoMPageOrderAsc, new NexmoRequestListener<NexmoEventsPage>() {
        @Override
        public void onSuccess(@Nullable NexmoEventsPage eventsPage) {
            processEvents(eventsPage.getPageResponse().getData());
        }

        @Override
        public void onError(@NonNull NexmoApiError apiError) {
            Log.d("TAG", "Error: Unable to load conversation events " + apiError.getMessage());
        }
    });
}

private void processEvents(Collection<NexmoEvent> events) {
    for (NexmoEvent event : events) {
        String message = "";

        if (event instanceof NexmoMemberEvent) {
            NexmoMemberEvent memberEvent = (NexmoMemberEvent) event;
            message = getEventText(memberEvent);
        }
        if (event instanceof NexmoTextEvent) {
            NexmoTextEvent textEvent = (NexmoTextEvent) event;
            message = getEventText(textEvent);
        }
        if (event instanceof NexmoSeenEvent) {
            NexmoSeenEvent seenEvent = (NexmoSeenEvent) event;
            message = getEventText(seenEvent);
        }
        if (event instanceof NexmoDeliveredEvent) {
            NexmoDeliveredEvent deliveredEvent = (NexmoDeliveredEvent) event;
            message = getEventText(deliveredEvent);
        }
        if (event instanceof NexmoTypingEvent) {
            NexmoTypingEvent typingEvent = (NexmoTypingEvent) event;
            getEventText(typingEvent);
        } else {
            message = "Unsupported event " + event.getEventType();
        }

        Log.d("TAG", (message);
    }
}

private String getEventText(NexmoTypingEvent typingEvent) {
    String user = typingEvent.getFromMember().getUser().getName();
    String typingState;

    if (typingEvent.getState() == NexmoTypingState.ON) {
        typingState = "typing";
    } else {
        typingState = "not typing";
    }

    return user + " is " + typingState;
}

private String getEventText(NexmoDeliveredEvent deliveredEvent) {
    String user = deliveredEvent.getFromMember().getUser().getName();
    return "Event from " + user + " with id " + deliveredEvent.initialEventId() + " delivered at " + deliveredEvent.initialEventId();
}

private String getEventText(NexmoSeenEvent seenEvent) {
    String user = seenEvent.getFromMember().getUser().getName();
    return user + " saw event with id " + seenEvent.initialEventId() + " at " + seenEvent.getCreationDate();
}

private String getEventText(NexmoTextEvent textEvent) {
    String user = textEvent.getFromMember().getUser().getName();
    return user + " said: " + textEvent.getText();
}

private String getEventText(NexmoMemberEvent memberEvent) {
    String user = memberEvent.getMember().getUser().getName();
    String event = memberEvent.getState().name();
    return user + " " + event;
}

The getEventsPageWithSize:order:completionHandler: method retrieves events that occurred in the context of the conversation via a NXMEventsPage:

conversation.getEventsPage(withSize: 20, order: .asc) { (error, eventsPage) in
    if let error = error {
        NSLog("Error retrieving events: \(error.localizedDescription)")
        return
    }
    guard let eventsPage = eventsPage else {
        return
    }

    // // events found - process them based on their type
    eventsPage.events.forEach({ (event) in
        if let memberEvent = event as? NXMMemberEvent {
            // show Member event
        }
        if let textEvent = event as? NXMTextEvent {
            // show Text event
        }
    })

    if eventsPage.hasNextPage() {
        eventsPage.nextPage({ (error, nextPage) in
            // process next page of events
        })
    }

    if eventsPage.hasPreviousPage() {
        eventsPage.previousPage({ (error, nextPage) in
            // process previous page of events
        })
    }
}

The getEventsPageWithSize:order:eventType:completionHandler: method retrieves events that occurred in the context of the conversation via a NXMEventsPage:

[self.conversation getEventsPageWithSize:20 order:NXMPageOrderAsc completionHandler:^(NSError * _Nullable error, NXMEventsPage * _Nullable eventsPage) {
    if (error) {
        NSLog(@"Error retrieving events: %@", error);
        return;
    }
    // events found - process them based on their type
    for(id event in eventsPage.events) {
        if ([event isKindOfClass: [NXMMemberEvent class]]) {
            // show Member event
        }
        if ([event isKindOfClass: [NXMTextEvent class]]) {
            // show Text event
        }
    }

    if (eventsPage.hasNextPage) {
        [eventsPage nextPage:^(NSError * _Nullable error, NXMEventsPage * _Nullable page) {
            // process next page of events
        }];
    }

    if (eventsPage.hasPreviousPage) {
        [eventsPage previousPage:^(NSError * _Nullable error, NXMEventsPage * _Nullable page) {
            // process previous page of events
        }];
    }
}];