Skip to content

Persistent Custom Fields in Zendesk Web Widget #88

@Fazliddin-04

Description

@Fazliddin-04

I’m implementing the Zendesk Web Widget (Classic) in my admin panel. There’s an additional custom field, “Restaurant”, that should be included when a new ticket is created as soon as the user starts a conversation.

Everything works fine with the first ticket creation. However, when the administrator/staff resolves the ticket, ends the session, and the user initiates a new conversation, the custom field is missing from the new ticket request. It is not being sent with the new ticket.

What could be causing this behavior? Is there a recommended way to ensure the custom field is retained for subsequent tickets or sessions?

Here is the main logic of my Zendesk implementation (the Provider is also added at the top level):

const InitialSettings = () => {
  const [hasAuthorized, setAuthorized] = useState(false);
  const { isOpen,  setLocale, setConversationFields } = useZendesk();

  const dispatch = useDispatch();
  const user = useSelector((state) => state.user);
  const zendeskToken = useSelector((state) => state.zendesk_session);

  useEffect(() => {
    let timeoutId = null;

    const initializeZendesk = async () => {
      // Check if we have required data and not already authorized
      if (
        user?.shipper_user_id &&
        typeof window?.zE !== "undefined" &&
        !hasAuthorized
      ) {
        try {
          const payload = {
            external_id: user?.user_id,
            scope: "user",
            name: user?.name,
          };

          let token = zendeskToken;
          if (!token) {
            // Get token for authorization
            const response = await zendeskService.getToken(payload);

            if (!response?.access_token) {
              // If token is not available, throw error to trigger retry
              throw new Error("Token not available");
            }

            token = response?.access_token;
            dispatch(authActions.saveZendeskToken(token));
          }

          // Attempt to login user
          window?.zE(
            "messenger",
            "loginUser",
            function jwtCallback(callback) {
              callback(token);
            },
            function loginCallback(error) {
              if (error) {
                // Rethrow to trigger retry
                console.log("Login failed:", error);
                throw new Error("Login failed");
              }

              // Success path - set authorized and complete setup
              setAuthorized(true);

              // Also set persistent user identity if available in API
              if (typeof window?.zE?.identify === "function") {
                window.zE.identify({
                  name: user?.name,
                  externalId: user?.user_id,
                });
              }

              // Set additional properties after successful login
              setLocale("ru");
              setConversationFields([
                {
                  id: "33011653597841",
                  value: user?.shipper_name || user?.branch_name,
                },
              ]);
            },
          );
        } catch (error) {
          console.log("Authorization attempt failed:", error);

          // Schedule a retry after delay
          timeoutId = setTimeout(() => {
            initializeZendesk();
          }, 3000); // Retry after 3 seconds
        }
      } else if (!user?.shipper_user_id && typeof window?.zE !== "undefined") {
        // Required data not available yet, schedule retry
        timeoutId = setTimeout(() => {
          initializeZendesk();
        }, 1000); // Check again after 1 second
      } else {
        // Schedule a retry after delay
        timeoutId = setTimeout(() => {
          initializeZendesk();
        }, 3000);
      }
    };

    // Start the initialization process
    initializeZendesk();

    // Return cleanup function
    return () => {
      if (timeoutId) {
        clearTimeout(timeoutId);
      }
    };
  }, [user, zendeskToken]);

  useEffect(() => {
    const updateZendeskFields = () => {
      if (user?.restaurant_name) {
        setConversationFields([
          {
            id: "33011653597841", // "Restaurant" field ID
            value: user?.restaurant_name,
          },
        ]);
      }
    };
    updateZendeskFields();
  }, [isOpen]);

  return null;
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions