+// whatsappContactName returns the name of the person jid: the full name, the
+// first name, the business name, or the push name of the contact in the session
+// of device, then push, the push name of a message, then the phone number. A
+// LID gets its phone number from the LID map of the session.
+func whatsappContactName(ctx context.Context, device *store.Device, jid types.JID, push string) string {
+ jid = jid.ToNonAD()
+ candidates := []types.JID{jid}
+ phone := types.EmptyJID
+ switch jid.Server {
+ case types.DefaultUserServer:
+ phone = jid
+ case types.HiddenUserServer:
+ mapped, err := device.LIDs.GetPNForLID(ctx, jid)
+ if err == nil && !mapped.IsEmpty() {
+ phone = mapped
+ candidates = append(candidates, mapped)
+ }
+ }
+
+ for _, candidate := range candidates {
+ contact, err := device.Contacts.GetContact(ctx, candidate)
+ if err != nil || !contact.Found {
+ continue
+ }
+
+ for _, name := range []string{contact.FullName, contact.FirstName, contact.BusinessName, contact.PushName} {
+ if name != "" {
+ return name
+ }
+ }
+ }
+
+ switch {
+ case push != "":
+ return push
+ case !phone.IsEmpty():
+ return "+" + phone.User
+ default:
+ return jid.User
+ }
+}
+
+// whatsappSendCheck returns the JID of chat, and an error when id, chat, or
+// text cannot go to a send. The chat is a private chat or a group, and not the
+// chat of the user with itself.
+func whatsappSendCheck(id, chat, text string, own []string) (types.JID, error) {
+ jid, err := types.ParseJID(chat)
+ switch {
+ case strings.TrimSpace(id) == "" || len(id) > whatsappSendIDBytes:
+ return types.EmptyJID, fmt.Errorf("the id must have 1 to %d bytes", whatsappSendIDBytes)
+ case strings.TrimSpace(text) == "" || len(text) > whatsappSendBytes:
+ return types.EmptyJID, fmt.Errorf("the text must have 1 to %d bytes", whatsappSendBytes)
+ case err != nil || jid.User == "" || jid != jid.ToNonAD() || jid.String() != chat:
+ return types.EmptyJID, fmt.Errorf("%q is not the ID of a WhatsApp chat: find the ID with whatsapp_find", chat)
+ case jid.Server != types.DefaultUserServer && jid.Server != types.HiddenUserServer && jid.Server != types.GroupServer:
+ return types.EmptyJID, fmt.Errorf("%q is not a private chat or a group", chat)
+ case slices.Contains(own, jid.User):
+ return types.EmptyJID, errors.New("this is the chat of the user with itself: send to another chat")
+ }
+
+ return jid, nil
+}
+