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

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