Custom Events
Custom events allow you to add custom metadata to conversations by recording data alongside your text or audio events. You can add events using the REST API or using the JavaScript SDK.
Creating a custom event
Each custom event consists of a unique type
and a data
. The type
has the following restrictions:
- Must not exceed 100 characters
- Must only contain alphanumeric,
-
and_
characters
In addition, the event data
must not exceed 4096 bytes.
Once you've installed the JavaScript Client SDK and have a conversation
object, you can call sendCustomEvent
to add a custom event to the conversation.
conversation.sendCustomEvent({ type: 'my_custom_event', body: { your: 'data' }}).then((custom_event) => {
console.log(custom_event);
});
conversation.sendCustomEvent("my_custom_event", hashMapOf("key" to "data"), object : NexmoRequestListener<Void> {
override fun onError(apiError: NexmoApiError) {
Log.d("TAG", "Custom event error")
}
override fun onSuccess(p0: Void?) {
Log.d("TAG", "Custom event sent")
}
})
HashMap<String, Object> data = new HashMap<>();
data.put("key", "data");
conversation.sendCustomEvent("my_custom_event", data, new NexmoRequestListener<Void>() {
public void onSuccess(@Nullable Void p0) {
Log.d("TAG", "Custom event sent");
}
public void onError(@NotNull NexmoApiError apiError) {
Log.d("TAG", "Custom event error");
}
});
Once you've installed the iOS Client SDK and have a conversation
object, you can call sendCustom(withEvent: data: completionHandler:)
to add a custom event to the conversation.
conversation.sendCustom(withEvent: "my_custom_event", data: ["your": "data"], completionHandler: { (error) in
if let error = error {
NSLog("Error sending custom event: \(error.localizedDescription)")
return
}
NSLog("Custom event sent.")
})
Once you've installed the iOS Client SDK and have a conversation
object, you can call sendCustomWithEvent:data:completionHandler:
to add a custom event to the conversation.
[conversation sendCustomWithEvent:@"my_custom_event" data:@{@"your": @"data"} completionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"Error sending custom event: %@", error);
return;
}
NSLog(@"Custom event sent.");
}];
Listening to custom events
In addition to adding custom events to the conversation, you can listen for custom events using the Client SDK. Register an event handler that listens for your custom event name:
conversation.on('my_custom_event', (from, event) => {
console.log(event.body);
});
val customEventListener = NexmoCustomEventListener {
Log.d("TAG", "Incoming custom event of type ${ it.customType} : ${it.data}")
}
conversation.addCustomEventListener(customEventListener)
private NexmoCustomEventListener customEventListener = new NexmoCustomEventListener() {
@Override
public void onCustomEvent(NexmoCustomEvent event) {
Log.d("TAG", "Incoming custom event of type " + event.getCustomType() + ": " + event.getData());
}
};
conversation.addCustomEventListener(customEventListener);
Implement conversation(_ conversation: NXMConversation, didReceive event: NXMCustomEvent)
, part of the NXMConversationDelegate
protocol:
func conversation(_ conversation: NXMConversation, didReceive event: NXMCustomEvent) {
NSLog("Received custom event with type \(String(describing: event.customType)): \(String(describing: event.data))");
}
Implement conversation:didReceiveCustomEvent:
:, part of the NXMConversationDelegate
protocol:
- (void)conversation:(NXMConversation *)conversation didReceiveCustomEvent:(NXMCustomEvent *)event {
NSLog(@"Received custom event with type %@: %@", event.customType, event.data);
}
Complete example
Here's an example application that registers a listener for my_custom_event
, then emits that event:
Make sure to replace YOUR_JWT
and YOUR_CONVERSATION_ID
with the relevant values.
<script src="./node_modules/nexmo-client/dist/nexmoClient.js"></script>
<script>
(async function() {
let nexmo = new NexmoClient();
let app = await nexmo.login(YOUR_JWT);
let c = await app.getConversation(YOUR_CONVERSATION_ID);
c.on('my_custom_event', (from, event) => {
console.log(event.body);
});
c.sendCustomEvent({ type: 'my_custom_event', body: { your: 'data' }}).then((custom_event) => {
console.log(custom_event);
});
})();
</script>
Troubleshooting
Object is missing self (me)
If you receive an error that states Object is missing self (me)
, ensure that the user you're authenticating as is a member of the conversation
class SendCustomEventActivity : AppCompatActivity() {
private val customEventListener = NexmoCustomEventListener {
Log.d("TAG", "Incoming custom event of type ${it.customType} : ${it.data}")
}
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
// No need for client initialization here. Client initialization is already done in BaseApplication class.
// NexmoClient.Builder().build(this)
val client = NexmoClient.get()
getConversation(client)
}
private fun getConversation(client: NexmoClient) {
client.getConversation("CONVERSATION_ID", object : NexmoRequestListener<NexmoConversation> {
override fun onSuccess(conversation: NexmoConversation?) {
Log.d("TAG", "Conversation loaded")
conversation?.let {
it.addCustomEventListener(customEventListener)
sendCustomEvent(it, "my_custom_event", hashMapOf("my_key" to "my_data"))
}
}
override fun onError(apiError: NexmoApiError) {
Log.d("TAG", "Error: Unable to load conversation ${apiError.message}")
}
})
}
private fun sendCustomEvent(conversation: NexmoConversation, eventType: String, data: HashMap<String, Any>) {
conversation.sendCustomEvent(eventType, data, object : NexmoRequestListener<Void> {
override fun onSuccess(p0: Void?) {
Log.d("TAG", "Custom event sent")
}
override fun onError(apiError: NexmoApiError) {
Log.d("TAG", "Custom event error")
}
})
}
}
import android.os.Bundle;
import android.os.PersistableBundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.nexmo.client.NexmoClient;
import com.nexmo.client.NexmoConversation;
import com.nexmo.client.NexmoCustomEvent;
import com.nexmo.client.NexmoCustomEventListener;
import com.nexmo.client.request_listener.NexmoApiError;
import com.nexmo.client.request_listener.NexmoRequestListener;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
public class SendCustomEventActivity extends AppCompatActivity {
private NexmoCustomEventListener customEventListener = new NexmoCustomEventListener() {
@Override
public void onCustomEvent(NexmoCustomEvent event) {
Log.d("TAG", "Incoming custom event of type " + event.getCustomType() + ": " + event.getData());
}
};
@Override
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
// No need for client initialization here. Client initialization is already done in BaseApplication class.
// new NexmoClient.Builder().build(this);
NexmoClient client = NexmoClient.get();
client.login("JWT token");
getConversation(client);
}
private void getConversation(NexmoClient client) {
client.getConversation("CONVERSATION_ID", new NexmoRequestListener<NexmoConversation>() {
@Override
public void onSuccess(@Nullable NexmoConversation conversation) {
Log.d("TAG", "Conversation loaded");
conversation.addCustomEventListener(customEventListener);
HashMap<String, Object> data = new HashMap<>();
data.put("my_key", "my_data");
sendCustomEvent(conversation, "my_custom_event", data);
}
@Override
public void onError(@NonNull NexmoApiError apiError) {
Log.d("TAG", "Error: Unable to load conversation" + apiError.getMessage());
}
});
}
private void sendCustomEvent(@NonNull NexmoConversation conversation, String eventType, HashMap<String, Object> data) {
conversation.sendCustomEvent(eventType, data, new NexmoRequestListener<Void>() {
public void onSuccess(@Nullable Void p0) {
Log.d("TAG", "Custom event sent");
}
public void onError(@NotNull NexmoApiError apiError) {
Log.d("TAG", "Custom event error");
}
});
}
}
class ConversationViewController: UIViewController {
var error: Error?
var conversation: NXMConversation?
override func viewDidLoad() {
super.viewDidLoad()
getConversation()
}
func getConversation() {
NXMClient.shared.getConversationWithUuid(conversationId) { [weak self] (error, conversation) in
self?.error = error
self?.conversation = conversation
conversation?.delegate = self
}
}
func sendCustomEvent() {
conversation?.sendCustom(withEvent: "my_custom_event", data: ["your": "data"], completionHandler: { (error) in
if let error = error {
NSLog("Error sending custom event: \(error.localizedDescription)")
return
}
NSLog("Custom event sent.")
})
}
}
//MARK: Conversation Delegate
extension ConversationViewController: NXMConversationDelegate {
func conversation(_ conversation: NXMConversation, didReceive error: Error) {
NSLog("Conversation error: \(error.localizedDescription)")
}
func conversation(_ conversation: NXMConversation, didReceive event: NXMCustomEvent) {
NSLog("Received custome type \(String(describing: event.customType)): \(String(describing: event.data))");
}
}
@interface ConversationViewController () <NXMConversationDelegate>
@property NSError *error;
@property NXMConversation *conversation;
@end
@implementation ConversationViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self getConversation];
}
- (void)getConversation {
[NXMClient.shared getConversationWithUuid:conversationUUID completionHandler:^(NSError * _Nullable error, NXMConversation * _Nullable conversation) {
self.error = error;
self.conversation = conversation;
[conversation setDelegate:self];
}];
}
- (void)sendCustomEvent {
[self.conversation sendCustomWithEvent:@"my_custom_event" data:@{@"your": @"data"} completionHandler:^(NSError * _Nullable error) {
if (error) {
NSLog(@"Error sending custom event: %@", error);
return;
}
NSLog(@"Custom event sent.");
}];
}
//MARK: Conversation Delegate
- (void)conversation:(NXMConversation *)conversation didReceive:(NSError *)error {
NSLog(@"Conversation error: %@", error.localizedDescription);
}
- (void)conversation:(NXMConversation *)conversation didReceiveCustomEvent:(NXMCustomEvent *)event {
NSLog(@"Received custome type %@: %@", event.customType, event.data);
}
@end