-// Find returns the contacts and the groups whose name contains name, with no
-// regard to case and accents, as lines "ID | name | contact" or "ID | name |
-// group", sorted by name. It gives at most whatsappFindMatches lines and the
-// number of the others. The contacts come from the session database, and the
-// groups from WhatsApp, read again after whatsappGroupsAge. When the groups
-// cannot be read and none are known, the answer says so. Before the names
-// arrive from the phone, it says that they are not ready.
-func (w *WhatsApp) Find(ctx context.Context, name string) (string, error) {
- w.mutex.Lock()
- linked := w.linked
- device := w.device
- own := slices.Clone(w.own)
- w.mutex.Unlock()
-
- stale := w.groups.stale()
-
- if !linked {
- return whatsappNotLinked, nil
- }
-
- query := whatsappFold(name)
- if query == "" {
- return "", errors.New("name is empty: give a part of the name of the contact or the group")
- }
-
- contacts, err := device.Contacts.GetAllContacts(ctx)
- if err != nil {
- return "", fmt.Errorf("read the contacts: %s", w.redact(err.Error()))
- }
-
- read := !stale || w.groups.read(ctx, w.link())
- groups := w.groups.all()
-
- if len(contacts) == 0 && len(groups) == 0 {
- if !read {
- return "The names are not known yet, and WhatsApp is disconnected, so the groups cannot be read. Try again later.", nil
- }
-
- return whatsappNamesNotReady, nil
- }
-
- var matches []WhatsAppMatch
- for jid, contact := range contacts {
- names := []string{contact.FullName, contact.FirstName, contact.BusinessName, contact.PushName}
- shown := slices.IndexFunc(names, func(name string) bool {
- return name != ""
- })
-
- if slices.Contains(own, jid.User) || shown < 0 || !slices.ContainsFunc(names, func(name string) bool {
- return strings.Contains(whatsappFold(name), query)
- }) {
- continue
- }
-
- matches = append(matches, WhatsAppMatch{
- id: jid.ToNonAD().String(),
- name: names[shown],
- kind: "contact",
- })
- }
-
- for id, group := range groups {
- if strings.Contains(whatsappFold(group), query) {
- matches = append(matches, WhatsAppMatch{
- id: id,
- name: group,
- kind: "group",
- })
- }
- }
-
- return whatsappFindAnswer(name, matches, read || len(groups) > 0), nil
-}
-