Rails 微信自定义菜单的 post

fizzwu · 2013年10月29日 · 最后由 as181920 回复于 2013年11月12日 · 10152 次阅读

有人搞过微信的自定义菜单吗?文档里说 post 一个 json 过去就完了,我直接用 curl 在命令行里面 post 倒是成功了,可是我写的 http post 老是返回 40016 错误,太奇怪了,难道是我 post 的方式有问题?

贴下我的代码:

request = Nestful.post menu_api_url, :params => menu_json_str

private
def menu_json_str
   s = {:button => [
     {:type => "click", :name => "Menu1", :key => "dfafd"},
   ]}.as_json
end

Nestful.post 'http://example.com?access_token=abc', {:foo => 'bar'}, :format => :json format 加上试试呢?

#1 楼 @joseen 这样我之前试过了,也不行的,提示 access_token missing 了

.... 你的 URL 里没有带 access_token 参数?

{"button":[{"name": "abc", "type": "click", "key":1}]} 你生成 json 的时候,以这样的格式提交试试? 把 as_json 改成 to_json

因为你提示了 access_token missing,看上去像是 access_token 错误的样子。 我这边使用是正常的。

但报 40016 错误是指“不合法的按钮个数” 大概只可能是 json 的参数格式或者 access_token 的错误。

#7 楼 @joseen to_json 之前我也试过了。。。方便的话能贴下你的代码片段不?我看下哪里不一样,谢谢

HTTParty.post "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=#{access_token}", body: @ui_menu_json, headers: {'ContentType' => 'application/json'}    

上面这个是我的,有效的代码。@ui_menu_json是 jbuilder 生成的 json 字符串(和 to_json 应该是一样的)

确认下你的请求参数是否对,params 这个 key 是否一定要,json 要不要带 headers 指定 contenttype

我的问题是没法送中文字符串(你测试记得也先用英文),参见http://ruby-china.org/topics/14873

顺道,今天微信开高级接口了,300 块买路费哈

RestClient.post "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=#{access_token}", menus_json

private
def menus_json
  Jbuilder.encode do |json|
     ....
  end
end

@as181920 我这里使用中文没有出现问题。

#12 楼 @joseen

[8] pry(#<UiMenusController>)> RestClient.post "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=#{access_token}", @ui_menu_json
=> "{\"errcode\":40033,\"errmsg\":\"invalid charset. please check your request, if include \\\\uxxxx will create fail!\"}"
[9] pry(#<UiMenusController>)> @ui_menu_json
=> "{\"button\":[{\"name\":\"kk\",\"sub_button\":[{\"name\":\"l;jaf\",\"type\":\"click\",\"key\":\"95a942b1-0144-4377-937f-49a81d59638f\"},{\"name\":\"lajsfd\",\"type\":\"click\",\"key\":\"9527e14b-4ac2-4a39-86dc-cd6163b609f8\"},{\"name\":\"aljsf\",\"type\":\"click\",\"key\":\"f10e8406-c764-43d2-b927-d98622188d15\"},{\"name\":\"\\u4e2d\\u6587\",\"type\":\"click\",\"key\":\"b34496b4-c96c-4d57-900d-643a0d09c5fa\"}]},{\"name\":\"mm\",\"type\":\"click\",\"key\":\"3964c5e9-588f-4525-b0ab-612610184b99\"},{\"name\":\"jas\",\"type\":\"click\",\"key\":\"558c1192-858d-4dea-9477-7b585a70e71d\"}]}"
[10] pry(#<UiMenusController>)> JSON.parse @ui_menu_json
=> {"button"=>
  [{"name"=>"kk",
    "sub_button"=>
     [{"name"=>"l;jaf",
       "type"=>"click",
       "key"=>"95a942b1-0144-4377-937f-49a81d59638f"},
      {"name"=>"lajsfd",
       "type"=>"click",
       "key"=>"9527e14b-4ac2-4a39-86dc-cd6163b609f8"},
      {"name"=>"aljsf",
       "type"=>"click",
       "key"=>"f10e8406-c764-43d2-b927-d98622188d15"},
      {"name"=>"中文",
       "type"=>"click",
       "key"=>"b34496b4-c96c-4d57-900d-643a0d09c5fa"}]},
   {"name"=>"mm",
    "type"=>"click",
    "key"=>"3964c5e9-588f-4525-b0ab-612610184b99"},
   {"name"=>"jas",
    "type"=>"click",
    "key"=>"558c1192-858d-4dea-9477-7b585a70e71d"}]}
[11] pry(#<UiMenusController>)> 

我的问题参见如上,就因为中间有中文,帮看下?

#12 楼 @joseen 补充

def build_json_menu(ui_menu)
  Jbuilder.encode do |json|
    json.button @ui_menu.ui_buttons do |ui_button|
      json.name ui_button.name
      if ui_button.sub_buttons.present?
        json.sub_button ui_button.sub_buttons do |sub_button|
          json.name sub_button.name
          json.type sub_button.btn_type
          case sub_button.btn_type
          when 'click'
            json.key sub_button.key
          when 'view'
            json.url sub_button.url
          else
          end
        end
      else
        json.type ui_button.btn_type
        case ui_button.btn_type
        when 'click'
          json.key ui_button.key
        when 'view'
          json.url ui_button.url
        else
        end
      end
    end
  end
end

@as181920 提示明确在编码问题上, 你看一下配置文件 application.rb 文件中的 config.encoding 是否配置为 UTF-8?

UTF-8 正解

@as181920,兄弟是在 windows 下干活的吧?

#15 楼 @joseen #17 楼 @otecteng windows 已经好多年不碰了,前面用 gentoo,现在偷懒一直用 ubuntu,默认和配置全部 utf-8

jossen 能弄一个带中文的 menus_json 看看么,我这里任何中文 to_json 后都是\uxxxx。

[1] pry(main)> "中文".to_json
=> "\"\\u4e2d\\u6587\""

而微信返回提示 \\uxxxx will create fail!\ 这里不清楚怎么回事

@as181920 ,我也用 ubuntu,utf-8,1.9.3 的 irb 没问题,不然你换个环境试试吧,微信的 meus_json 都是中文的吧,heh

我的和@otecteng 的环境一样,估计是你@as181920的环境配置上有问题。

猜测你可能就是 POST 的参数和 format 的问题,Nestful 不熟,是不是 POST JSON 的时候,URL 的参数会被过滤掉?我是这么做的,没有问题,body 就是整个菜单的 Hash

url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=#{access_token}"
response = Typhoeus::Request.post(url, body: body.to_json, timeout: 3000)

不行你就把它现 POST 到你本机,看看能收到什么

@joseen @otecteng @as181920

感谢楼上几位兄弟,中文的问题,我用 stackoverflow 里的一个帖子的办法解决了,就是用正则把 encode 过的 json string 再转回去,就正常了

json_string.gsub!(/\\u([0-9a-z]{4})/) {|s| [$1.to_i(16)].pack("U")}
需要 登录 后方可回复, 如果你还没有账号请 注册新账号