code: func (h *apiExecutor) Presence(ctx context.Context, cmd *PresenceRequest) *PresenceResponse {
  	defer func(started time.Time) {
  		apiCommandDurationSummary.WithLabelValues(h.protocol, "presence").Observe(time.Since(started).Seconds())
  	}(time.Now())
  
  	resp := &PresenceResponse{}
  
  	ch := cmd.Channel
  
  	if ch == "" {
  		resp.Error = ErrorBadRequest
  		return resp
  	}
  
  	chOpts, ok := h.node.ChannelOpts(ch)
  	if !ok {
  		resp.Error = ErrorNamespaceNotFound
  		return resp
  	}
  
  	if !chOpts.Presence {
  		resp.Error = ErrorNotAvailable
  		return resp
  	}
  
  	presence, err := h.node.Presence(ch)
  	if err != nil {
  		h.node.Log(centrifuge.NewLogEntry(centrifuge.LogLevelError, "error calling presence", map[string]interface{}{"error": err.Error()}))
  		resp.Error = ErrorInternal
  		return resp
  	}
  
  	apiPresence := make(map[string]*ClientInfo, len(presence))
  	for k, v := range presence {
  		apiPresence[k] = &ClientInfo{
  			User:     v.User,
  			Client:   v.Client,
  			ConnInfo: Raw(v.ConnInfo),
  			ChanInfo: Raw(v.ChanInfo),
  		}
  	}
  
  	resp.Result = &PresenceResult{
  		Presence: apiPresence,
  	}
  	return resp
  }
docs: // Presence returns response with presence information for channel.