Chef - assign a value to variable in execution or converge phase
You have a problem of compile vs converge times as you guessed.

You code between the execute resource and the ruby_block resource is executed before the execute resource is converged.

The easiest way to circumvent that is to put that code within a ruby_block, and to avoid scoping problem use node.run_state hash to store the value to be checked.

A rewrite of your recipe which should work would be:

#
# Cookbook:: test_cookbook
# Recipe:: check-vpn-ip
#
# Copyright:: 2019, The Authors, All Rights Reserved.

#Getting the IP address using the ruby's Socket class.

ip_list = Socket.ip_address_list
vpn_ip_list = ip_list.select{ |ip| ip.ip_address.match(/^10.12/) }
!vpn_ip_list.empty? ? ip_addr = vpn_ip_list.first.ip_address : ip_addr = ""

execute 'manually_start_open_vpn' do
  command "sudo openvpn #{node['openvpn-conf-path']}/#{host}.conf &amp;"
  action :nothing
  only_if {ip_addr.length.eql?(0)}
end

ruby_block 'check_vpn_ip_list' do
  block do
    new_ip_list = Socket.ip_address_list
    new_vpn_ip_list = new_ip_list.select{ |ip| ip.ip_address.match(/^10.12/) }
    node.run_state['newvpn_ip_addr'] = !new_vpn_ip_list.empty? ?  new_vpn_ip_list.first.ip_address : ""
  end
end

ruby_block 'chat-bot' do
  block do
    machine_data = {text: "OpenVPN IP not assigned to #{host} 
        software_version: 18.4.4 \n This is a test message please 
        ignore @all"}.to_json 
    header = {'Content-Type': 'text/json'}
    http = Net::HTTP.new(google_chat_uri.host,                       google_chat_uri.port)
    http.use_ssl = true
    request = Net::HTTP::Post.new(google_chat_uri.request_uri, header)
    request.body = machine_data
    response = http.request(request)
  end
  only_if {node.run_state['newvpn_ip_addr'].length.eql?(0)}
  action :nothing
end 


There's no real use of response = in the last line as you don't use it later, but I let it as is in case you wish to log in the ruby block the response.