Konwersacje sterowane zdarzeniami przy użyciu programu obsługi działań
Artykuł
DOTYCZY: ZESTAW SDK w wersji 4
Procedura obsługi działań to oparty na zdarzeniach sposób organizowania logiki konwersacyjnej bota.
Każdy inny typ lub podtyp działania reprezentuje inny typ zdarzenia konwersacyjnego.
W ramach objęć program obsługi kolei bota wywołuje program obsługi poszczególnych działań dla dowolnego typu otrzymanego działania.
Jeśli na przykład bot otrzyma działanie komunikatu, program obsługi kolei zobaczy działanie przychodzące i wyśle je do programu obsługi działań związanych z działaniem komunikatu. Podczas tworzenia bota logika bota do obsługi komunikatów i odpowiadania na nie przejdzie w procedurze obsługi działań komunikatów. Podobnie logika obsługi elementów członkowskich dodawanych do konwersacji będzie przechodzić do procedury obsługi dodanej przez członków , która jest wywoływana za każdym razem, gdy członek zostanie dodany do konwersacji.
Aby zapoznać się z innymi sposobami organizowania logiki bota, zobacz sekcję logiki bota w sposobie działania botów.
Uwaga
Zestawy SDK języka JavaScript, C# i Python platformy Bot Framework będą nadal obsługiwane, jednak zestaw SDK języka Java jest wycofywany z ostatecznym długoterminowym wsparciem kończącym się w listopadzie 2023 r.
Istniejące boty utworzone za pomocą zestawu JAVA SDK będą nadal działać.
Aby zaimplementować logikę dla tych procedur obsługi, zastąpisz te metody w botze, na przykład w poniższej sekcji przykładowej procedury obsługi działań. Dla każdego z tych programów obsługi nie ma implementacji podstawowej, więc wystarczy dodać logikę, która ma zostać zastąpiona.
Istnieją pewne sytuacje, w których należy zastąpić program obsługi kolei podstawowej, na przykład stan zapisywania na końcu kolei. W tym celu należy najpierw wywołać metodę await base.OnTurnAsync(turnContext, cancellationToken); , aby upewnić się, że podstawowa implementacja OnTurnAsync programu jest uruchamiana przed dodatkowym kodem. Ta podstawowa implementacja jest między innymi odpowiedzialna za wywoływanie pozostałych procedur obsługi działań, takich jak OnMessageActivityAsync.
Język JavaScript ActivityHandler używa wzorca emitera zdarzeń i odbiornika.
Na przykład użyj onMessage metody , aby zarejestrować odbiornik zdarzeń na potrzeby działań komunikatów. Można zarejestrować więcej niż jeden odbiornik. Gdy bot odbiera działanie komunikatu, program obsługi działań będzie widzieć to działanie przychodzące i wysyłać je do każdego z onMessage odbiorników działań w kolejności, w jakiej zostały zarejestrowane.
Podczas tworzenia bota logika bota do obsługi komunikatów i odpowiadania na nie zostanie dodana do onMessage odbiorników. Podobnie logika obsługi elementów członkowskich dodawanych do konwersacji będzie przebiegać w onMembersAdded odbiornikach, które są wywoływane za każdym razem, gdy członek zostanie dodany do konwersacji.
Aby dodać te odbiorniki, zarejestrujesz je w botze, jak pokazano w poniższej sekcji logiki bota . Dla każdego odbiornika dołącz logikę bota, a następnie pamiętaj o wywołaniu next() na końcu. Wywołając metodę next(), upewnij się, że następny odbiornik jest uruchomiony.
Pamiętaj, aby zapisać stan przed zakończeniem kolei. Można to zrobić, przesłaniając metodę obsługi run działań i zapisując stan po zakończeniu metody elementu nadrzędnego run .
Nie ma typowych sytuacji, w których należy przesłonić program obsługi kolei podstawowej, więc należy zachować ostrożność, jeśli spróbujesz to zrobić.
Istnieje specjalny program obsługi o nazwie onDialog. Procedura onDialog obsługi jest uruchamiana na końcu, po uruchomieniu pozostałych procedur obsługi i nie jest powiązana z określonym typem działania. Podobnie jak w przypadku wszystkich powyższych procedur obsługi, pamiętaj, aby next() upewnić się, że reszta procesu się kończy.
Aby zaimplementować logikę dla tych procedur obsługi, zastąpisz te metody w botze, na przykład w poniższej sekcji przykładowej procedury obsługi działań. Nie ma podstawowej implementacji dla każdego z tych programów obsługi, więc dodaj logikę, którą chcesz zastąpić.
Istnieją pewne sytuacje, w których należy zastąpić program obsługi kolei podstawowej, na przykład stan zapisywania na końcu kolei. W tym celu należy najpierw wywołać super.onTurn(turnContext); metodę , aby upewnić się, że podstawowa implementacja onTurn programu jest uruchamiana przed dodatkowym kodem. Ta podstawowa implementacja jest między innymi odpowiedzialna za wywoływanie pozostałych procedur obsługi działań, takich jak onMessageActivity.
Podczas tworzenia bota logika bota do obsługi komunikatów i odpowiadania na nie przejdzie w tej on_message_activity procedurze obsługi. Podobnie logika obsługi elementów członkowskich dodawanych do konwersacji będzie przebiegać w on_members_added procedurze obsługi, która jest wywoływana za każdym razem, gdy członek zostanie dodany do konwersacji.
Jeśli na przykład bot otrzyma działanie komunikatu, program obsługi kolei zobaczy działanie przychodzące i wyśle je do on_message_activity programu obsługi działań.
Aby zaimplementować logikę dla tych procedur obsługi, zastąpisz te metody w botze, na przykład w poniższej sekcji przykładowej procedury obsługi działań. Dla każdego z tych programów obsługi nie ma implementacji podstawowej, więc wystarczy dodać logikę, która ma zostać zastąpiona.
Istnieją pewne sytuacje, w których należy zastąpić program obsługi kolei podstawowej, na przykład stan zapisywania na końcu kolei. W tym celu należy najpierw wywołać metodę await super().on_turn(turnContext); , aby upewnić się, że podstawowa implementacja on_turn programu jest uruchamiana przed dodatkowym kodem. Ta podstawowa implementacja jest między innymi odpowiedzialna za wywoływanie pozostałych procedur obsługi działań, takich jak on_message_activity.
Obsługa działań
Logika bota przetwarza przychodzące działania z co najmniej jednego kanału i generuje działania wychodzące w odpowiedzi.
Główna logika bota jest definiowana w kodzie bota. Aby zaimplementować bota jako program obsługi działań, utwórz klasę bota z ActivityHandlerklasy , która implementuje IBot interfejs. ActivityHandler definiuje różne procedury obsługi dla różnych typów działań, takich jak OnMessageActivityAsync, i OnMembersAddedAsync. Te metody są chronione, ale można je zastąpić, ponieważ pochodzimy z ActivityHandlerklasy .
Programy obsługi zdefiniowane w programie ActivityHandler to:
Zdarzenie
Program obsługi
opis
Odebrano dowolny typ działania
OnTurnAsync
Wywołuje jedną z innych procedur obsługi na podstawie typu odebranego działania.
Odebrano działanie komunikatu
OnMessageActivityAsync
Zastąpij message to, aby obsłużyć działanie.
Odebrano działanie aktualizacji konwersacji
OnConversationUpdateActivityAsync
W przypadku działania wywołuje procedurę conversationUpdate obsługi, jeśli członkowie inni niż bot dołączyli lub opuścili konwersację.
Członkowie niebędący botami dołączyli do konwersacji
OnMembersAddedAsync
Zastąp to, aby obsługiwać członków dołączania do konwersacji.
Członkowie niebędący botami opuszczają konwersację
OnMembersRemovedAsync
Zastąpij tę opcję, aby obsługiwać członków opuszczających konwersację.
Odebrano działanie zdarzenia
OnEventActivityAsync
W przypadku działania wywołuje procedurę event obsługi specyficzną dla typu zdarzenia.
Odebrano działanie zdarzenia odpowiedzi tokenu
OnTokenResponseEventAsync
Zastąp to w celu obsługi zdarzeń odpowiedzi tokenu.
Odebrano działanie zdarzenia nienależące do tokenu
OnEventAsync
Zastąpij to w celu obsługi innych typów zdarzeń.
Odebrano działanie reakcji komunikatu
OnMessageReactionActivityAsync
W przypadku działania wywołuje procedurę messageReaction obsługi, jeśli co najmniej jedna reakcja została dodana lub usunięta z komunikatu.
Reakcje komunikatów dodane do komunikatu
OnReactionsAddedAsync
Zastąpij to, aby obsługiwać reakcje dodane do komunikatu.
Reakcje komunikatów usunięte z komunikatu
OnReactionsRemovedAsync
Zastąpij to w celu obsługi reakcji usuniętych z komunikatu.
Odebrano działanie aktualizacji instalacji
OnInstallationUpdateActivityAsync
W ramach installationUpdate działania wywołuje program obsługi na podstawie tego, czy bot został zainstalowany, czy odinstalowany.
Zainstalowany bot
OnInstallationUpdateAddAsync
Zastąpij tę opcję, aby dodać logikę, gdy bot jest zainstalowany w jednostce organizacyjnej.
Odinstalowany bot
OnInstallationUpdateRemoveAsync
Zastąpij tę opcję, aby dodać logikę w przypadku odinstalowania bota w jednostce organizacyjnej.
Odebrano inny typ działania
OnUnrecognizedActivityTypeAsync
Zastąp to, aby obsłużyć dowolny typ działania w inny sposób nieobsługiwany.
Te różne programy obsługi mają element turnContext , który zawiera informacje o działaniu przychodzącym, który odpowiada przychodzącemu żądaniu HTTP. Działania mogą być różnego typu, więc każda procedura obsługi zapewnia silnie typizowane działanie w parametrze kontekstu kolei; w większości przypadków OnMessageActivityAsync będzie zawsze obsługiwana i jest na ogół najbardziej powszechna.
Podobnie jak w poprzednich wersjach 4.x tej platformy, istnieje również opcja implementacji metody OnTurnAsyncpublicznej . Obecnie podstawowa implementacja tej metody obsługuje sprawdzanie błędów, a następnie wywołuje każde z określonych procedur obsługi (takich jak te, które definiujemy w tym przykładzie) w zależności od typu działania przychodzącego. W większości przypadków można pozostawić tę metodę samodzielnie i użyć poszczególnych procedur obsługi, ale jeśli sytuacja wymaga niestandardowej implementacji OnTurnAsync, nadal jest to opcja.
Ważne
Jeśli zastąpisz metodę OnTurnAsync , musisz wywołać base.OnTurnAsync metodę , aby uzyskać implementację podstawową w celu wywołania wszystkich innych On<activity>Async procedur obsługi lub wywołania tych procedur obsługi samodzielnie. W przeciwnym razie te programy obsługi nie będą wywoływane i ten kod nie zostanie uruchomiony.
Główna logika bota jest definiowana w kodzie bota. Aby zaimplementować bota jako program obsługi działań, rozszerz rozszerzenie ActivityHandler. ActivityHandler definiuje różne zdarzenia dla różnych typów działań i można zmodyfikować zachowanie bota, rejestrując odbiorniki zdarzeń, takie jak i onMessageonConversationUpdate.
Użyj tych metod, aby zarejestrować odbiorniki dla każdego typu zdarzenia:
Zdarzenie
Metoda rejestracji
opis
Odebrano dowolny typ działania
onTurn
Rejestruje odbiornik w przypadku odebrania dowolnego działania.
Odebrano działanie komunikatu
onMessage
Rejestruje odbiornik w przypadku odebrania message działania.
Odebrano działanie aktualizacji konwersacji
onConversationUpdate
Rejestruje odbiornik w przypadku odebrania dowolnego conversationUpdate działania.
Członkowie dołączyli do konwersacji
onMembersAdded
Rejestruje odbiornik, gdy członkowie dołączyli do konwersacji, w tym bot.
Członkowie opuścili konwersację
onMembersRemoved
Rejestruje odbiornik, gdy członkowie opuszczają konwersację, w tym bota.
Odebrano działanie reakcji komunikatu
onMessageReaction
Rejestruje odbiornik w przypadku odebrania dowolnego messageReaction działania.
Reakcje komunikatów dodane do komunikatu
onReactionsAdded
Rejestruje odbiornik w przypadku dodawania reakcji do komunikatu.
Reakcje komunikatów usunięte z komunikatu
onReactionsRemoved
Rejestruje odbiornik w przypadku usunięcia reakcji z komunikatu.
Odebrano działanie zdarzenia
onEvent
Rejestruje odbiornik w przypadku odebrania dowolnego event działania.
Odebrano działanie zdarzenia odpowiedzi tokenu
onTokenResponseEvent
Rejestruje odbiornik w przypadku odebrania tokens/response zdarzenia.
Odebrano działanie aktualizacji instalacji
onInstallationUpdate
Rejestruje odbiornik w przypadku odebrania dowolnego installationUpdate działania.
Zainstalowany bot
onInstallationUpdateAdd
Rejestruje odbiornik, gdy bot jest zainstalowany w jednostce organizacyjnej.
Odinstalowany bot
onInstallationUpdateRemove
Rejestruje odbiornik w przypadku odinstalowania bota w jednostce organizacyjnej.
Odebrano inny typ działania
onUnrecognizedActivityType
Rejestruje odbiornik, gdy program obsługi dla określonego typu działania nie jest zdefiniowany.
Programy obsługi działań zostały ukończone
onDialog
Wywoływane po zakończeniu wszystkich odpowiednich procedur obsługi.
Wywołaj funkcję kontynuacji next z każdej procedury obsługi, aby umożliwić kontynuowanie przetwarzania. Jeśli next nie zostanie wywołana, przetwarzanie działania kończy się.
Główna logika bota jest definiowana w kodzie bota. Aby zaimplementować bota jako program obsługi działań, utwórz klasę bota z ActivityHandlerklasy , która implementuje Bot interfejs. ActivityHandler definiuje różne procedury obsługi dla różnych typów działań, takich jak onMessageActivity, i onMembersAdded. Te metody są chronione, ale można je zastąpić, ponieważ pochodzimy z ActivityHandlerklasy .
Programy obsługi zdefiniowane w programie ActivityHandler to:
Zdarzenie
Program obsługi
opis
Odebrano dowolny typ działania
onTurn
Wywołuje jedną z innych procedur obsługi na podstawie typu odebranego działania.
Odebrano działanie komunikatu
onMessageActivity
Zastąpij message to, aby obsłużyć działanie.
Odebrano działanie aktualizacji konwersacji
onConversationUpdateActivity
W przypadku działania wywołuje procedurę conversationUpdate obsługi, jeśli członkowie inni niż bot dołączyli lub opuścili konwersację.
Członkowie niebędący botami dołączyli do konwersacji
onMembersAdded
Zastąp to, aby obsługiwać członków dołączania do konwersacji.
Członkowie niebędący botami opuszczają konwersację
onMembersRemoved
Zastąpij tę opcję, aby obsługiwać członków opuszczających konwersację.
Odebrano działanie zdarzenia
onEventActivity
W przypadku działania wywołuje procedurę event obsługi specyficzną dla typu zdarzenia.
Odebrano działanie zdarzenia odpowiedzi tokenu
onTokenResponseEvent
Zastąp to w celu obsługi zdarzeń odpowiedzi tokenu.
Odebrano działanie zdarzenia nienależące do tokenu
onEvent
Zastąpij to w celu obsługi innych typów zdarzeń.
Odebrano działanie reakcji komunikatu
onMessageReactionActivity
W przypadku działania wywołuje procedurę messageReaction obsługi, jeśli co najmniej jedna reakcja została dodana lub usunięta z komunikatu.
Reakcje komunikatów dodane do komunikatu
onReactionsAdded
Zastąpij to, aby obsługiwać reakcje dodane do komunikatu.
Reakcje komunikatów usunięte z komunikatu
onReactionsRemoved
Zastąpij to w celu obsługi reakcji usuniętych z komunikatu.
Odebrano działanie aktualizacji instalacji
onInstallationUpdate
W ramach installationUpdate działania wywołuje program obsługi na podstawie tego, czy bot został zainstalowany, czy odinstalowany.
Zainstalowany bot
onInstallationUpdateAdd
Zastąpij tę opcję, aby dodać logikę, gdy bot jest zainstalowany w jednostce organizacyjnej.
Odinstalowany bot
onInstallationUpdateRemove
Zastąpij tę opcję, aby dodać logikę w przypadku odinstalowania bota w jednostce organizacyjnej.
Odebrano inny typ działania
onUnrecognizedActivityType
Zastąp to, aby obsłużyć dowolny typ działania w inny sposób nieobsługiwany.
Te różne programy obsługi mają element turnContext , który zawiera informacje o działaniu przychodzącym, który odpowiada przychodzącemu żądaniu HTTP. Działania mogą być różnego typu, więc każda procedura obsługi zapewnia silnie typizowane działanie w parametrze kontekstu kolei; w większości przypadków onMessageActivity będzie zawsze obsługiwana i jest na ogół najbardziej powszechna.
Istnieje również opcja zaimplementowania metody onTurnpublicznej . Obecnie podstawowa implementacja tej metody obsługuje sprawdzanie błędów, a następnie wywołuje każde z określonych procedur obsługi (takich jak te, które definiujemy w tym przykładzie) w zależności od typu działania przychodzącego. W większości przypadków można pozostawić tę metodę samodzielnie i użyć poszczególnych procedur obsługi, ale jeśli sytuacja wymaga niestandardowej implementacji onTurn, nadal jest to opcja.
Ważne
Jeśli zastąpisz metodę onTurn , musisz wywołać super.onTurn metodę , aby uzyskać implementację podstawową w celu wywołania wszystkich innych on<activity> procedur obsługi lub wywołania tych procedur obsługi samodzielnie. W przeciwnym razie te programy obsługi nie będą wywoływane i ten kod nie zostanie uruchomiony.
Główna logika bota jest definiowana w kodzie bota. Aby zaimplementować bota jako program obsługi działań, utwórz klasę bota z ActivityHandlerklasy , która z kolei pochodzi z klasy abstrakcyjnej Bot . ActivityHandler definiuje różne procedury obsługi dla różnych typów działań, takich jak on_message_activity i on_members_added. Te metody są chronione, ale można je zastąpić, ponieważ pochodzimy z ActivityHandlerklasy .
Programy obsługi zdefiniowane w programie ActivityHandler to:
Zdarzenie
Program obsługi
opis
Odebrano dowolny typ działania
on_turn
Wywołuje jedną z innych procedur obsługi na podstawie typu odebranego działania.
Odebrano działanie komunikatu
on_message_activity
Zastąpij message to, aby obsłużyć działanie.
Odebrano działanie aktualizacji konwersacji
on_conversation_update_activity
W przypadku działania wywołuje procedurę conversationUpdate obsługi, jeśli członkowie inni niż bot dołączyli lub opuścili konwersację.
Członkowie niebędący botami dołączyli do konwersacji
on_members_added_activity
Zastąp to, aby obsługiwać członków dołączania do konwersacji.
Członkowie niebędący botami opuszczają konwersację
on_members_removed_activity
Zastąpij tę opcję, aby obsługiwać członków opuszczających konwersację.
Odebrano działanie zdarzenia
on_event_activity
W przypadku działania wywołuje procedurę event obsługi specyficzną dla typu zdarzenia.
Odebrano działanie zdarzenia odpowiedzi tokenu
on_token_response_event
Zastąp to w celu obsługi zdarzeń odpowiedzi tokenu.
Odebrano działanie zdarzenia nienależące do tokenu
on_event_activity
Zastąpij to w celu obsługi innych typów zdarzeń.
Odebrano działanie reakcji komunikatu
on_message_reaction_activity
W przypadku działania wywołuje procedurę messageReaction obsługi, jeśli co najmniej jedna reakcja została dodana lub usunięta z komunikatu.
Reakcje komunikatów dodane do komunikatu
on_reactions_added
Zastąpij to, aby obsługiwać reakcje dodane do komunikatu.
Reakcje komunikatów usunięte z komunikatu
on_reactions_removed
Zastąpij to w celu obsługi reakcji usuniętych z komunikatu.
Odebrano działanie aktualizacji instalacji
on_installation_update
W ramach installationUpdate działania wywołuje program obsługi na podstawie tego, czy bot został zainstalowany, czy odinstalowany.
Zainstalowany bot
on_installation_update_add
Zastąpij tę opcję, aby dodać logikę, gdy bot jest zainstalowany w jednostce organizacyjnej.
Odinstalowany bot
on_installation_update_remove
Zastąpij tę opcję, aby dodać logikę w przypadku odinstalowania bota w jednostce organizacyjnej.
Odebrano inny typ działania
on_unrecognized_activity_type
Zastąp to, aby obsłużyć dowolny typ działania w inny sposób nieobsługiwany.
Te różne programy obsługi mają element turn_context , który zawiera informacje o działaniu przychodzącym, który odpowiada przychodzącemu żądaniu HTTP. Działania mogą być różnego typu, więc każda procedura obsługi zapewnia silnie typizowane działanie w parametrze kontekstu kolei; w większości przypadków on_message_activity będzie zawsze obsługiwana i jest na ogół najbardziej powszechna.
Podobnie jak w poprzednich wersjach 4.x tej platformy, istnieje również opcja implementacji metody on_turnpublicznej . Obecnie podstawowa implementacja tej metody obsługuje sprawdzanie błędów, a następnie wywołuje każde z określonych procedur obsługi (takich jak te, które definiujemy w tym przykładzie) w zależności od typu działania przychodzącego. W większości przypadków można pozostawić tę metodę samodzielnie i użyć poszczególnych procedur obsługi, ale jeśli sytuacja wymaga niestandardowej implementacji on_turn, nadal jest to opcja.
Ważne
Jeśli zastąpisz metodę on_turn , musisz wywołać super().on_turn metodę , aby uzyskać implementację podstawową w celu wywołania wszystkich innych on_<activity> procedur obsługi lub wywołania tych procedur obsługi samodzielnie. W przeciwnym razie te programy obsługi nie będą wywoływane i ten kod nie zostanie uruchomiony.
Przykładowa procedura obsługi działań
Możesz na przykład obsługiwać członków dodanych do powitalnych użytkowników do konwersacji i obsługiwać wiadomości w celu echa wiadomości wysyłanych do bota.
public class EchoBot : ActivityHandler
{
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var replyText = $"Echo: {turnContext.Activity.Text}";
await turnContext.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);
}
protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
var welcomeText = "Hello and welcome!";
foreach (var member in membersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
await turnContext.SendActivityAsync(MessageFactory.Text(welcomeText, welcomeText), cancellationToken);
}
}
}
}
class EchoBot extends ActivityHandler {
constructor() {
super();
// See https://aka.ms/about-bot-activity-message to learn more about the message and other activity types.
this.onMessage(async (context, next) => {
const replyText = `Echo: ${ context.activity.text }`;
await context.sendActivity(MessageFactory.text(replyText, replyText));
// By calling next() you ensure that the next BotHandler is run.
await next();
});
this.onMembersAdded(async (context, next) => {
const membersAdded = context.activity.membersAdded;
const welcomeText = 'Hello and welcome!';
for (let cnt = 0; cnt < membersAdded.length; ++cnt) {
if (membersAdded[cnt].id !== context.activity.recipient.id) {
await context.sendActivity(MessageFactory.text(welcomeText, welcomeText));
}
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
}
}
class EchoBot(ActivityHandler):
async def on_members_added_activity(
self, members_added: [ChannelAccount], turn_context: TurnContext
):
for member in members_added:
if member.id != turn_context.activity.recipient.id:
await turn_context.send_activity("Hello and welcome!")
async def on_message_activity(self, turn_context: TurnContext):
return await turn_context.send_activity(
MessageFactory.text(f"Echo: {turn_context.activity.text}")
)
Następne kroki
Kanał usługi Microsoft Teams wprowadza niektóre działania specyficzne dla usługi Teams, które bot będzie musiał obsługiwać, aby działał prawidłowo z usługą Teams. Aby zrozumieć kluczowe pojęcia związane z opracowywaniem botów dla usługi Microsoft Teams, zobacz Jak działają boty usługi Microsoft Teams
Procedura obsługi działań to dobry sposób projektowania bota, który nie musi śledzić stanu konwersacji między zakrętami. Biblioteka okien dialogowych udostępnia sposoby zarządzania długotrwałą konwersacją z użytkownikiem.