1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/Eric-Guo-wechat

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

WeChat Gem Version Build Status Maintainability Test Coverage

Присоединиться к чату

Китайская документация

WeChat — это китайское многофункциональное приложение для мгновенного обмена сообщениями, социальных сетей и мобильной оплаты, созданное компанией Tencent. Оно было выпущено впервые в 2011 году, а к 2018 году стало одним из крупнейших самостоятельных мобильных приложений по количеству ежемесячно активных пользователей, с более чем 1 миллиардом ежемесячно активных пользователей (902 миллиона ежедневно активных пользователей). (Согласно википедии)

Gem WeChat помогает разработчикам Rails легко интегрировать платформу официальных аккаунтов WeChat или микросайта WeChat, включая следующие возможности:- API отправки сообщений (send message) (можно использовать как через консоль, так и через сервер Rails)

  • API приема сообщений (receive messages and events) (необходим запущенный сервер Rails)
  • Конфигурация подписи для WeChat JS-SDK (configuration of signature for WeChat JS-SDK)
  • Аутентификация OAuth 2.0
  • Запись сессий при получении сообщений от пользователя (опционально)Команда wechat использует ту же самую API в консоли, поэтому вы можете быстро взаимодействовать с сервером WeChat без запуска среды веб-кода.

DSL-шаблон отклика может использоваться в контроллере Rails, что позволяет использовать событийно-ориентированное интерфейс для обработки сообщений, отправленных конечными пользователями. Если ваше приложение требует WeChat OAuth 2.0, рекомендуется использовать omniauth-wechat-oauth2 для применения devise аутентификации.

Если в проекте используется стиль UI от Tencent weui, доступен гем weui-rails.

Для веб-страниц с приложением WeChat, пожалуйста, используйте wechat_api, которое содержит только веб-функциональность, в отличие от традиционного типа сообщений wechat_responder.

Существует более полная демонстрация wechat-starter, которая дополнительно включает функцию платежного SDK.

Установка

Используйте gem install

gem install "wechat"
# Если версия Ruby меньше 2.6
# gem install wechat -v 0.12.4

Или добавьте его в ваш Gemfile:

gem 'wechat'
# Если версия Rails меньше 6.0
# gem 'wechat', '~> 0.12.4'

Запустите следующую команду для установки:

bundle install

Запустите генератор:

rails generate wechat:install
```Команда `rails g wechat:install` создаёт начальный конфигурационный файл `wechat.yml`, который включает пример контроллера WeChat и соответствующие маршруты.Активируйте запись сессий:

```console
rails g wechat:session
rake db:migrate

Активация записи сессий создаст два файла в папке Rails; вы можете добавить дополнительные столбцы в таблицу wechat_session и объявить связь с таблицей пользователей. Также можно хранить данные непосредственно в hash_store. Если вы используете PostgreSQL, использование hstore/json может быть лучше, но лучшим способом является добавление специального столбца для записи данных (способ Rails).

Использование Redis для хранения токена и билета WeChat:

rails g wechat:redis_store

Хранение Redis поддерживает приложения Rails, работающие на нескольких серверах. Рекомендуется использовать файловое хранилище по умолчанию, если используется один сервер. Кроме того, команда wechat не будет читать токены/билеты, хранящиеся в Redis.

Активировать базу данных для конфигураций WeChat:

rails g wechat:config
rake db:migrate

После выполнения миграции будет создана таблица wechat_configs, которая позволяет хранить несколько аккаунтов WeChat. ## Конфигурация

Настройка WeChat в первый раз

Убедитесь, что завершены все настройки с серверной части на основе Ruby on Rails, затем отправьте эти настройки на сайт управления WeChat от компании Tencent. В противном случае, WeChat выдаст ошибку.

Адрес URL, созданный выполнением команды rails g wechat:install, будет иметь вид http://ваш_сервер.com/wechat.Для настройки appid/corpid и секрета см. ниже раздел.

Настройка WeChat методом на основе записей

Убедитесь, что атрибуты record содержат access_token, token_expires_in, got_token_at.

def client
  @client ||= Wechat::Api.new(app_id, app_secret, token_file, network_setting, jsapi_ticket_file, record)
end

Настройка для командной строки

Чтобы использовать автономную команду wechat, вам потребуется создать конфигурационный файл ~/.wechat.yml и включить следующий контент для публичного аккаунта. Атрибут access_token будет записываться в файл /var/tmp/wechat_access_token.

appid: "my_appid"
secret: "my_secret"
access_token: "/var/tmp/wechat_access_token"

Для корпоративного аккаунта следует использовать corpid вместо appid, так как корпоративный аккаунт поддерживает несколько приложений (которые Tencent называет агентами) в одном аккаунте. Получение corpsecret немного сложнее — его необходимо создать в режиме управления -> настройках привилегий и создать любую группу управления для получения доступа. Учитывая, что Tencent предоставляет китайский интерфейс для своей консоли управления, настоятельно рекомендуется найти коллегу, который знает мандаринский китайский язык, чтобы помочь вам получить corpsecret.

Пользователям Windows требуется хранить .wechat.yml в директории C:\Users\[имя пользователя] (замените имя пользователя на ваше), также обратите внимание на направление разделителя каталога.``` corpid: "my_appid" corpsecret: "my_secret" agentid: 1 # целое число, которое можно получить из настроек приложения access_token: "C:/Users/[имя пользователя]/wechat_access_token"


### Настройка для Ruby on Rails

Файл конфигурации Ruby on Rails поддерживает различные окружения аналогично файлу `database.yml`. После выполнения команды `rails generate wechat:install` вы можете найти файл конфигурации в директории `config/wechat.yml`.

Пример конфигурации для публичного аккаунта:

default: &default appid: "app_id" secret: "app_secret" token: "app_token" access_token: "/var/tmp/wechat_access_token" jsapi_ticket: "/var/tmp/wechat_jsapi_ticket"

production:
  appid: <%= ENV['WECHAT_APPID'] %>
  secret: <%= ENV['WECHAT_APP_SECRET'] %>
  token:   <%= ENV['WECHAT_TOKEN'] %>
  access_token: <%= ENV['WECHAT_ACCESS_TOKEN'] %>
  jsapi_ticket: <%= ENV['WECHAT_JSAPI_TICKET'] %>
  oauth2_cookie_duration: <%= ENV['WECHAT_OAUTH2_COOKIE_DURATION'] %> # секунды

development:
  <<: *default
  trusted_domain_fullname: "http://your_dev.proxy.qqbrowser.cc"

test:
  <<: *default

Хотя это опционально для публичного аккаунта, но настоятельно рекомендуется включить режим шифрования, добавив следующие два элемента в файл wechat.yml.

default: &default
  encrypt_mode: true
  encoding_aes_key: "my_encoding_aes_key"

Аккаунты корпоративного типа должны использовать режим шифрования (encrypt_mode: true активирован по умолчанию, дополнительное конфигурирование не требуется).

Значения token и encoding_aes_key можно получить из управления консоли -> одного из приложений агента -> выбор режима, выбрать режим обратного вызова и установить/получить значения.```yaml default: &default corpid: "corpid" corpsecret: "corpsecret" agentid: 1 access_token: "C:/Users/[user_name]/wechat_access_token" token: "" encoding_aes_key: "" jsapi_ticket: "C:/Users/[user_name]/wechat_jsapi_ticket"

production: corpid: <%= ENV['WECHAT_CORPID'] %> corpsecret: <%= ENV['WECHAT_CORPSECRET'] %> agentid: <%= ENV['WECHAT_AGENTID'] %> access_token: <%= ENV['WECHAT_ACCESS_TOKEN'] %> token: <%= ENV['WECHAT_TOKEN'] %> timeout: 30 skip_verify_ssl: true # не рекомендовано encoding_aes_key: <%= ENV['WECHAT_ENCODING_AES_KEY'] %> jsapi_ticket: <%= ENV['WECHAT_JSAPI_TICKET'] %> oauth2_cookie_duration: <%= ENV['WECHAT_OAUTH2_COOKIE_DURATION'] %>

development: <<: *default trusted_domain_fullname: "http://your_dev.proxy.qqbrowser.cc"

test: <<: *default

Поддержка нескольких аккаунтов

wx2_development:

<<: *default

appid: "my_appid"

secret: "my_secret"

access_token: "tmp/wechat_access_token2"

jsapi_ticket: "tmp/wechat_jsapi_ticket2"

wx2_test:

<<: *default

appid: "my_appid"

secret: "my_secret"

wx2_production:

<<: *default

appid: "my_appid"

secret: "my_secret"


Примечания по поддержке нескольких аккаунтов платформы `WeChat Official Accounts` / `WeChat Enterprise` (например, добавление аккаунта `wx2`). Конфигурация для нескольких аккаунтов аналогична конфигурации многобазовых систем в файле `config/database.yml`, где сегменты `development`, `test`, `production` являются базовой конфигурацией, а для добавления дополнительного аккаунта с названием `wx2` требуется добавление `wx2_development`, `wx2_test`, `wx2_production`.

Объявление дополнительного `wechat_responder`:
```ruby
wechat_responder account: :wx2

Используйте Wechat.api или Wechat.api(:default), чтобы представить основной API WeChat. Используйте Wechat.api(:wx2), чтобы вызвать API WeChat для аккаунта wx2.

  • При использовании командной строки WeChat (Wechat command line) можно переключиться на другой аккаунт WeChat, добавив опциональные параметры -a ACCOUNT [--account=ACCOUNT].

Для получения подробностей о поддержке нескольких аккаунтов, пожалуйста, проверьте PR 150.

Для мини-программы WeChat можно указать элементом type:

# Аккаунты мини-программ

  mini_development:
    <<: *default
    appid: "my_appid"
    secret: "my_secret"
    # `mp` — это сокращение от **mini program** (мини-программа)
    type: 'mp'

Конфигурация аккаунта WeChat в базе данных

После активации конфигурации аккаунта в базе данных будет создана следующая таблица:Атрибут Тип Примечание
environment string Обязательное поле. Окружение конфигурации аккаунта. Типичные значения: production, development и test. Например, конфигурация production будет доступна только в окружении production. По умолчанию равно development.
account string Обязательное поле. Уникальное имя аккаунта WeChat. Имена аккаунтов должны быть уникальными в каждом окружении.
enabled boolean Обязательное поле. Отображает активирован ли этот аккаунт. По умолчанию равно true.
appid string ID публичного аккаунта. Либо это поле, либо corpid должно быть указано.
secret string Настройки публичного аккаунта. Обязательное поле при наличии поля appid.
corpid string ID корпоративного аккаунта. Либо это поле, либо appid должно быть указано.
corpsecret string Настройки корпоративного аккаунта. Обязательное поле при наличии поля corpid.
agentid integer Настройки корпоративного аккаунта. Обязательное поле при наличии поля corpid.
encrypt_mode boolean
encoding_aes_key string Обязательное поле при значении encrypt_mode равном true.
token string Обязательное поле.
access_token string Обязательное поле. Путь к файлу хранения access token.
jsapi_ticket string Обязательное поле. Путь к файлу хранения jsapi ticket.
skip_verify_ssl boolean
timeout integer По умолчанию равно 20.
trusted_domain_fullname string После обновления конфигураций аккаунтов базы данных вам потребуется перезапустить сервер или вызвать Wechat.reload_config! для перезагрузки обновлений.##### Настройка приоритета

Выполнение команды wechat в корневой папке приложения Rails будет использовать конфигурацию Rails в первую очередь (default раздел). Если она не найдена, будет использоваться ~/.wechat.yml. Такое поведение позволяет управлять большим количеством аккаунтов WeChat для бизнеса и публичных аккаунтов без изменения домашнего файла ~/.wechat.yml.

Когда активирована конфигурация аккаунта базы данных, конфигурации базы данных будут загружены после файла конфигурации .yml или параметров окружения. Когда конфигурации с одинаковым именем аккаунта существуют как в базе данных, так и в файле .yml или параметрах окружения, конфигурация из базы данных имеет приоритет.

Настройка времени ожидания сервера WeChat

Стабильность сервиса WeChat от Tencent может меняться, поэтому может потребоваться установка большего времени ожидания; значение по умолчанию — 20 секунд, если не указано иначе.

Пропуск проверки SSL

Сертификат SSL также может быть поврежден по какой-то причине в Китае, это сообщено и если это произошло с вами, вы можете установить skip_verify_ssl: true. (не рекомендовано)

Конфигурирование отдельного ответчика с различными appidИногда вам может потребоваться хостить более одного аккаунта WeChat для бизнеса или публичных аккаунтов в одном приложении Rails. Поэтому вы можете предоставлять эту информацию в конфигурации при вызове wechat_responder или wechat_api.```ruby

class WechatFirstController < ActionController::Base wechat_responder account: :new_account, account_from_request: Proc.new { |request| request.params[:wechat] }

on :text, with: "помощь", respond: "контент помощи" end


Или вы можете предоставить полный список опций.

```ruby
class WechatFirstController < ActionController::Base
   wechat_responder appid: "app1", secret: "secret1", token: "token1", access_token: Rails.root.join("tmp/access_token1"),
                    account_from_request: Proc.new { |request| request.params[:wechat] }

   on :text, with: "помощь", respond: "контент помощи"
end

account_from_request — это Proc, который принимает параметр request и возвращает соответствующее имя аккаунта WeChat. В приведённых выше примерах controller выбирает аккаунт на основе параметра wechat, переданного в запросе. Если account_from_request не указан или этот Proc вернёт nil, используется конфигурация, указанная параметром account или полным списком опций.

Вспомогательный модуль JS-SDK

JS-SDK позволяет контролировать поведение приложения WeChat в HTML путём внедрения конфигурационной подписи. Вспомогательный модуль wechat_config_js выполняет эту задачу простым способом:

Чтобы сделать wechat_config_js работоспособным, вам нужно сначала поместить либо wechat_api, либо wechat_responder в контроллер.

<body>
<%= wechat_config_js debug: false, api: %w(скрытьМенюЭлементы закрытьОкно) -%>
<script type="application/javascript">
  wx.ready(function() {
      wx.hideOptionMenu();
  });
</script>
<a href="javascript:wx.closeWindow();">Закрыть</a>
</body>
```Настройте `trusted_domain_fullname`, если вы работаете в режиме разработки и ваше приложение запущено за прокси-сервером обратного запроса; в противном случае плагин WeChat не сможет получить правильный URL для последующей подписи.#### Аутентификация OAuth2.0

Для публичного аккаунта следующий код получает информацию о пользователе.

```ruby
class CartController < ActionController::Base
  wechat_api
  def index
    wechat_oauth2 do |openid|
      @current_user = User.find_by(wechat_openid: openid)
      @articles = @current_user.articles
    end

    # Укажите account_name для использования произвольной конфигурации аккаунта WeChat
    # wechat_oauth2('snsapi_base', nil, account_name) do |openid|
    #  ...
    # end
  end
end

Для корпоративного аккаунта следующий код получает информацию о сотруднике предприятия.

class WechatsController < ActionController::Base
  layout 'wechat'
  wechat_responder
  def apply_new
    wechat_oauth2 do |userid|
      @current_user = User.find_by(wechat_userid: userid)
      @apply = Apply.new
      @apply.user_id = @current_user.id
    end
  end
end

Метод wechat_oauth2 уже реализует необходимую логику аутентификации OAuth2.0 и работы с cookies. userid определяется как UserID сотрудника предприятия, а openid — как ID пользователя, который подписан на публичный аккаунт. Обратите внимание, что openid будет различаться для одного и того же пользователя, если он подписан на различные публичные аккаунты.

Примечание:

  • Если вы используете wechat_responder в своём контроллере, вы не сможете использовать действия create и show в этом контроллере, иначе возникнут ошибки.
  • Если вы видите сообщение об ошибке "redirect_uri parameter error", убедитесь, что вы правильно указали значение callback URL в консоли управления WeChat по пути Development center / Webpage service / Webpage authorization for retrieving user basic information.wechat gems не будут обрабатывать какие-либо исключения с привилегиями (кроме истечения срока действия токена, что не имеет значения для вас, так как в gems предусмотрено автоматическое повторное выполнение/восстановление), однако Tencent контролирует множество привилегий в зависимости от типа вашего публичного аккаунта и сертификации. Для получения более подробной информации обратитесь к официальной документации.

Командная строка

Доступный API различается между публичным аккаунтом и корпоративным аккаунтом, поэтому мы предоставляем различные наборы команд.

Не беспокойтесь, если вы не можете читать китайский в комментариях, он сохранен там для удобства копирования и поиска в официальной документации.#### Командная строка для публичного аккаунта

$ wechat
WeChat Public Account commands:
    wechat addvoicetotranscriptfortext [VOICE_ID]                 # Подача аудиофайла для распознавания в виде текста через API
    wechat callbackip                                             # Получение IP адреса сервера WeChat
    wechat clear_quota                                            # Сброс количества вызовов API до нуля
    wechat custom_image [OPENID, IMAGE_PATH]                      # Отправка сообщения с изображением для службы поддержки клиентов
    wechat custom_music [OPENID, THUMBNAIL_PATH, MUSIC_URL]       # Отправка сообщения с музыкальным треком для службы поддержки клиентов
    wechat custom_news [OPENID, NEWS_YAML_PATH]                   # Отправка сообщения с новостями для службы поддержки клиентов
    wechat custom_text [OPENID, TEXT_MESSAGE]                     # Отправка текстового сообщения для службы поддержки клиентов
    wechat custom_video [OPENID, VIDEO_PATH]                      # Отправка видео сообщения для службы поддержки клиентов
    wechat custom_voice [OPENID, VOICE_PATH]                      # Отправка голосового сообщения для службы поддержки клиентов
    wechat customservice_getonlinekflist                           # Получение информации о текущих онлайн сотрудниках службы поддержки клиентов
    wechat group_create [GROUP_NAME]                              # Создание группы
    wechat group_delete [GROUP_ID]                                # Удаление группы
    wechat group_update [GROUP_ID, NEW_GROUP_NAME]                # Изменение имени группы
    wechat groups                                                 # Получение всех групп
    wechat material_get [MEDIA_ID, PATH]                          # Скачивание постоянного медиафайла
```   wechat material_add [MEDIA_TYPE, PATH]                         # Загрузка постоянного медиафайла
   wechat material_add_news [MPNEWS_YAML_PATH]                    # Загрузка постоянного материала с новостями
   wechat material_count                                          # Получение общего количества постоянных материалов
   wechat material_delete [MEDIA_ID]                              # Удаление постоянного материала
   wechat material_list [TYPE, OFFSET, COUNT]                     # Получение списка постоянных материалов
   wechat media [MEDIA_ID, PATH]                                  # Скачивание медиафайла
   wechat media_hq [MEDIA_ID, PATH]                               # Скачивание высококачественного аудиофайла
   wechat media_create [MEDIA_TYPE, PATH]                         # Загрузка медиафайла
   wechat media_uploadimg [IMAGE_PATH]                            # Загрузка изображения для сообщения с новостями
   wechat media_uploadnews [MPNEWS_YAML_PATH]                     # Загрузка материала с новостями
   wechat menu                                                    # Текущее меню
   wechat menu_addconditional [CONDITIONAL_MENU_YAML_PATH]        # Создание условного меню

wechat menu_create [MENU_YAML_PATH] # Создание меню wechat menu_delconditional [MENU_ID] # Удаление условного меню wechat menu_delete # Удаление меню wechat menu_trymatch [USER_ID] # Тестирование соответствия условного меню wechat message_mass_delete [MSG_ID] # Удаление массового сообщения wechat message_mass_get [MSG_ID] # Получение состояния отправки массового сообщения wechat message_mass_preview [WX_NAME, MPNEWS_MEDIA_ID] # Предварительный просмотр материала с текстовым содержимым

  wechat qrcode_create_scene [SCENE_ID_OR_STR, EXPIRE_SECONDS]  # Запрос временного QR-кода
  wechat qrcode_download [TICKET, QR_CODE_PIC_PATH]             # Загрузка QR-кода по тикету
  wechat queryrecoresultfortext [VOICE_ID]                      # API распознавания речи — получение результата распознавания
  wechat shorturl [LONG_URL]                                    # Преобразование длинной ссылки в короткую
  wechat tag [TAGID]                                            # Получение списка подписчиков по метке
  wechat tag_add_user [TAG_ID, OPEN_IDS]                        # Добавление меток группе пользователей
  wechat tag_create [TAGNAME, TAG_ID]                           # Создание метки
  wechat tag_del_user [TAG_ID, OPEN_IDS]                        # Удаление меток у группы пользователей
  wechat tag_delete [TAG_ID]                                    # Удаление метки
  wechat tag_update [TAG_ID, TAGNAME]                           # Обновление имени метки
  wechat tags                                                   # Получение всех меток
  wechat template_message [OPENID, TEMPLATE_YAML_PATH]          # Шаблон сообщения
  wechat translatecontent [CONTENT]                             # API перевода — перевод контента
  wechat user [OPEN_ID]                                         # Получение базовой информации пользователя
  wechat user_batchget [OPEN_ID_LIST]                           # Получение базовой информации группы пользователей
  wechat user_change_group [OPEN_ID, TO_GROUP_ID]               # Изменение группы пользователя
  wechat user_group [OPEN_ID]                                   # Получение текущей группы пользователя
  wechat user_update_remark [OPEN_ID, REMARK]                   # Обновление примечания пользователя  мычэт юзерс                                                  # Список подписчиков мычэт wxa_msg_sec_check [КОНТЕНТ]                            # проверяет, содержит ли текст запрещенный или незаконный контент.
    мычэт wxacode_download [WXA_CODE_PIC_PATH, ПУТЬ, ШИРИНА]      # скачивает код мини-приложения
    мычэт клэр_квота                                            # сброс количества вызовов API до нуля
```#### Команды командной строки для корпоративного аккаунта WeChat

$ мычэт Команды корпоративного аккаунта WeChat: мычэт агэнт [АГЭНТ_ИД] # Получение деталей агента корпоративного аккаунта мычэт агэнт_лист # Получение списка агентов мычэт батч_джоб_резулт [ДЖОБ_ИД] # Получение результата асинхронной задачи мычэт батч_реплейспарти [БАТЧ_ПАРТИ_СВМ_ИД] # Полное замещение отделов мычэт батч_реплейсузер [БАТЧ_ЮЗЕР_СВМ_ИД] # Полное замещение участников мычэт батч_синкюзер [СИНК_ЮЗЕР_СВМ_ИД] # Инкрементальное обновление участников мычэт кэбэкіп # Получение IP адреса сервера WeChat мычэт клэр_квота # Обнуление количества вызовов API мычэт конверт_то_openid [ЮЗЕР_ИД] # Преобразование ЮЗЕР_ИД в OPENID мычэт конверт_то_юзерид [ОПЕНІД] # Преобразование ОПЕНІД в ЮЗЕР_ИД мычэт кастом_имэдж [ОПЕНІД, ИМЭЖ_ПАТХ] # Отправка сообщения с изображением через службу поддержки мычэт кастом_мьюzik [ОПЕНІД, ТХУМБНАЙЛ_ПАТХ, МЬЮZ_URL] # Отправка сообщения с музыкой через службу поддержки мычэт кастом_ньюс [ОПЕНІД, НЬЮС_ЯМЛ_ПАТХ] # Отправка сообщения с новостями через службу поддержки wechat custom_text [OPENID, TEXT_MESSAGE] # Отправка текстового сообщения через службу поддержки wechat custom_video [OPENID, VIDEO_PATH] # Отправка видео сообщения через службу поддержки wechat custom_voice [OPENID, VOICE_PATH] # Отправка голосового сообщения через службу поддержки wechat department [DEPARTMENT_ID] # Получение списка отделов wechat department_create [NAME, PARENT_ID] # Создание нового отдела wechat department_delete [DEPARTMENT_ID] # Удаление отдела wechat department_update [DEPARTMENT_ID, NAME] # Обновление названия отдела wechat getusercumulate [BEGIN_DATE, END_DATE] # Получение данных о накопленных пользователях wechat getusersummary [BEGIN_DATE, END_DATE] # Получение данных о изменениях пользователей wechat invite_user [USER_ID] # Приглашение пользователя присоединиться wechat material [MEDIA_ID, PATH] # Скачивание постоянного медиа контента wechat material_add [MEDIA_TYPE, PATH] # Загрузка постоянного медиа контента wechat material_count # Получение общего количества постоянного медиа контента wechat material_delete [MEDIA_ID] # Удаление постоянного медиа контента wechat material_list [TYPE, OFFSET, COUNT] # Получение списка постоянного медиа контента

wechat media [MEDIA_ID, PATH]                            # Загрузка медиафайлов
    wechat media_create [MEDIA_TYPE, PATH]                   # Создание медиафайлов
    wechat media_hq [MEDIA_ID, PATH]                         # Загрузка высококачественного аудиофайла
```   wechat media_uploadimg [IMAGE_PATH]                       # Загрузка изображения для сообщения с картинками
   wechat menu                                             # Текущее меню
   wechat menu_addconditional [CONDITIONAL_MENU_YAML_PATH]  # Создание условного меню
   wechat menu_create [MENU_YAML_PATH]                      # Создание меню
   wechat menu_delconditional [MENU_ID]                     # Удаление условного меню
   wechat menu_delete                                     # Удаление меню
   wechat menu_trymatch [USER_ID]                          # Тестирование соответствия условного меню
   wechat message_send [OPENID, TEXT_MESSAGE]              # Отправка текстового сообщения
   wechat qrcode_download [TICKET, QR_CODE_PIC_PATH]       # Загрузка QR-кода по тикету
   wechat tag [TAG_ID]                                     # Получение членства в метках
   wechat tag_add_department [TAG_ID, PARTY_IDS]           # Добавление отдела в метку
   wechat tag_add_user [TAG_ID, USER_IDS]                  # Добавление пользователя в метку
   wechat tag_create [TAG_NAME, TAG_ID]                    # Создание метки
   wechat tag_del_department [TAG_ID, PARTY_IDS]           # Удаление отдела из метки
   wechat tag_del_user [TAG_ID, USER_IDS]                 # Удаление пользователя из метки
   wechat tag_delete [TAG_ID]                              # Удаление метки
   wechat tag_update [TAG_ID, TAG_NAME]                   # Обновление имени метки
   wechat tags                                            # Получение всех меток
   wechat template_message [OPENID, TEMPLATE_YAML_PATH]   # Шаблон сообщения
   wechat upload_replaceparty [BATCH_PARTY_CSV_PATH]      # Полная замена отделов путём загрузки файла
   wechat upload_replaceuser [BATCH_USER_CSV_PATH]        # Полная замена пользователей путём загрузки файла   wechat user [OPEN_ID]                                    # Получение базовой информации о пользователе
    wechat user_batchdelete [USER_ID_LIST]                   # Блоковое удаление пользователей
    wechat user_create [USER_ID, NAME]                       # Создание пользователя
    wechat user_delete [USER_ID]                             # Удаление пользователя
    wechat user_list [DEPARTMENT_ID]                         # Получение подробной информации о пользователях отдела
    wechat user_simplelist [DEPARTMENT_ID]                   # Получение списка пользователей отдела
    мы используем `wechat user_update_remark [OPEN_ID, REMARK]`               # Установка заметок```Примечание: `replaceparty` полная загрузка отделов поддерживает только один корневой узел как отдел и не поддерживает параллельные множественные корневые узлы.

### Пример использования командной строки (частично)

#### Получение всех открытых ID пользователей

$ wechat users

{"total"=>4, "count"=>4, "data"=>{"openid"=>["oCfEht9***********", "oCfEhtwqa***********", "oCfEht9oMCqGo***********", "oCfEht_81H5o2***********"]}, "next_openid"=>"oCfEht_81H5o2***********"}


#### Получение информации о пользователе

$ wechat user "oCfEht9***********"

{"subscribe"=>1, "openid"=>"oCfEht9***********", "nickname"=>"Nickname", "sex"=>1, "language"=>"zh_CN", "city"=>"徐汇", "province"=>"上海", "country"=>"中国", "headimgurl"=>"http://wx.qlogo.cn/mmopen/ajNVdqHZLLBd0SG8NjV3UpXZuiaGGPDcaKHebTKiaTyof*********/0", "subscribe_time"=>1395715239}


#### Получение меню

$ wechat menu

{"menu"=>{"button"=>[{"type"=>"view", "name"=>"защищённое", "url"=>"http:///protected", "sub_button"=>[]}, {"type"=>"view", "name"=>"общедоступное", "url"=>"http://", "sub_button"=>[]}]}}


#### Создание меню

Запустите команду `rails g wechat:menu`, чтобы сгенерировать файл определения меню в формате YAML:

button:

name: "Хочу" sub_button:

type: "scancode_waitmsg"
name: "Привязать QR-код для питания"
key: "BINDING_QR_CODE"
type: "click"
name: "Забронировать обед"
key: "BOOK_LUNCH"
type: "miniprogram"
name: "Пример мини-приложения"
url: "http://ericguo.com/"
appid: "wx1234567890"
pagepath: "pages/index"

name: "Проверка" sub_button:

type: "click"
name: "Запись входа/выхода"
key: "BADGE_IN_OUT"
type: "click"
name: "Остаток отпуска"
key: "ANNUAL_LEAVE"

type: "view" name: "О нас" url: "http://blog.cloud-mes.com/"


Запустите следующую команду для загрузки меню:

```
$ wechat menu_create menu.yaml
```

Внимание: убедитесь, что у вас есть права управления для этого приложения, в противном случае вы получите ошибку [60011](http://qydev.weixin.qq.com/wiki/index.php?title=全局返回码说明).

#### Отправка пользовательской новости

Отправка пользовательской новости также должна быть определена в виде файла YAML, такого как `articles.yml`.

```
articles:
 -
  title: "Выступление президента Си Цзиньпина в Европейском университете Брюсселя"
  description: "新华网比利时布鲁日 4 月 1 日电 国家主席习近平 1 日在比利时布鲁日欧洲学院发表重要讲话"
  url: "http://news.sina.com.cn/c/2014-04-01/232629843387.shtml"
  pic_url: "http://i3.sinaimg.cn/dy/c/2014-04-01/1396366518_bYays1.jpg"
```

После этого вы можете выполнить следующую команду:

```
$ wechat custom_news oCfEht9oM*********** articles.yml
```

#### Отправка шаблонного сообщения

Отправка шаблонного сообщения с помощью файла YAML аналогична. Определите `template.yml`, а содержание будет просто шаблонным контентом.

```
template:
  template_id: "o64KQ62_xxxxxxxxxxxxxxx-Qz-MlNcRKteq8"
  url: "http://weixin.qq.com/download"
  topcolor: "#FF0000"
  data:
    first:
      value: "Привет, вы успешно зарегистрировались"
      color: "#0A0A0A"
    keynote1:
      value: "Здоровье бег 5км"
      color: "#CCCCCC"
    keynote2:
      value: "2014-09-16"
      color: "#CCCCCC"
    keynote3:
      value: "Центральный парк,浦东上海"
      color: "#CCCCCC"
    remark:
      value: "Добро пожаловать обратно"
      color: "#173177"
```

После этого вы можете выполнить следующую команду:

$ мычат_шаблонное_сообщение oCfEht9oM*********** template.yml


В коде:

```ruby
template = YAML.load(File.read(template_yaml_path))
Wechat.api.шаблонное_сообщение_отправить Wechat::Сообщение.к_получателю(openid).шаблон(template["template"])

Если использовать wechat_api или wechat_responder в контроллере, можно также использовать wechat как сокращение (поддерживает несколько аккаунтов):

template = YAML.load(File.read(template_yaml_path))
wechat.шаблонное_сообщение_отправить Wechat::Сообщение.к_получателю(openid).шаблон(template["template"])

wechat_api — Rails Controller Wechat API

Хотя пользователи всегда могут получить доступ ко всем функциям WeChat через Wechat.api, но настоятельно рекомендуется использовать wechat непосредственно в контроллере. Это обязательно требуется, если планируете поддерживать несколько аккаунтов, и помогает отделить логику WeChat от модели.

class WechatReportsController < ApplicationController
  wechat_api
  layout 'wechat'

  def index
    @lots = Lot.with_preloading.wip_lot
  end
end

Использование wechat api в ActiveJob/Rake задачах

Используйте Wechat.api для доступа к функциям WeChat API в любом месте.

Ниже приведён пример вызова API распознавания голоса через rails console:

# Аудиофайл с версией ID3 2.4.0, содержит: MPEG ADTS, layer III, v2,  40 kbps, 16 kHz, Mono
test_voice_file='test_voice.mp3'
Wechat.api.добавить_голос_для_распознавания_текста('test_voice_id', File.open(test_voice_file))
Wechat.api.получить_результат_распознавания_текста 'test_voice_id'

Проверка подписи

Используйте Wechat.дешифровать(зашифрованные_данные, сессионный_ключ, iv) для декодирования данных. Подробнее в разделе Проверка подписи.## wechat_responder — DSL контроллера ответа для Rails

Чтобы отвечать на сообщение, отправленное пользователем, разработчику Rails необходимо создать контроллер ответа wechat и определить маршруты в routes.rb.

resources :wechat, only: [:show, :create]

Таким образом, ActionController должен быть определён следующим образом:

class WechatsController < ActionController::Base
  wechat_responder

  # По умолчанию используется текстовый ответ при отсутствии других совпадений
  on :text do |request, content|
    request.reply.text "echo: #{content}" # Просто эхо
  end

  # При получении слова 'help', будет активирован этот ответ
  on :text, with: 'help' do |request|
    request.reply.text 'help content'
  end

  # При получении '<n>news', будет сопоставлено и количество новостей будет равно <n>
  on :text, with: /^(\d+) news$/ do |request, count|
    # В WeChat статьи могут содержать максимум 8 элементов, больше 8 будут удалены.
    news = (1..count.to_i).each_with_object([]) { |n, memo| memo << { title: 'Название новости', content: "Новость №#{n}" } }
    request.reply.news(news) do |article, n, index| # article — это объект ответа
      article.item title: "#{index}. #{n[:title]}", description: n[:content], pic_url: 'http://www.baidu.com/img/bdlogo.gif', url: 'http://www.baidu.com/'
    end
  end

  on :event, with: 'subscribe' do |request|
    request.reply.text "#{request[:FromUserName]} подписался сейчас"
  end
end
```  # Когда пользователь отписывается, сканируя QR-code qrscene_xxxxxx для подписки в публичном аккаунте,
  # следует отметить, что пользователь одновременно подписывается в публичном аккаунте, поэтому событие подписки больше не будет вызвано.
  on :scan, with: 'qrscene_xxxxxx' do |request, ticket|
    request.reply.text "Отписавшийся пользователь #{request[:FromUserName]} Билет #{ticket}"
  end  # Когда пользователь подписывается, сканируя scene_id в публичном аккаунте
  on :scan, with: 'scene_id' do |request, ticket|
    request.reply.text "Подписавшийся пользователь #{request[:FromUserName]} Билет #{ticket}"
  end

  # Когда ни один из ответов на события scan не может быть использован для подписавшегося пользователя,
  # который сканировал scene_id
  on :event, with: 'scan' do |request|
    if request[:EventKey].present?
      request.reply.text "Событие scan получил EventKey #{request[:EventKey]} Билет #{request[:Ticket]}"
    end
  end
end

Когда корпоративный пользователь нажимает меню BINDING_QR_CODE и успешно сканирует штрихкод

on :scan, with: 'BINDING_QR_CODE' do |request, scan_result, scan_type| request.reply.text "Пользователь #{request[:FromUserName]} результат сканирования #{scan_result} тип сканирования #{scan_type}" end

Кроме QR-кода, WeChat также может сканировать штрихкод CODE_39 в корпоративном аккаунте

on :scan, with: 'BINDING_BARCODE' do |message, scan_result| if scan_result.start_with?('CODE_39,') message.reply.text "Пользователь: #{message[:FromUserName]} сканирование штрихкода, результат #{scan_result.split(',')[1]}" end end

Когда пользователь нажимает кнопку меню

on :click, with: 'BOOK_LUNCH' do |request, key| request.reply.text "Пользователь: #{request[:FromUserName]} нажал #{key}" end

Когда пользователь просматривает URL в кнопке меню

on :view, with: 'http://wechat.somewhere.com/view_url' do |request, view| request.reply.text "#{request[:FromUserName]} просмотрел #{view}" end

Когда пользователь отправляет изображение

on :image do |request| request.reply.image(request[:MediaId]) # Отправка отправленного изображения обратно пользователю end # Когда пользователь отправляет голосовое сообщение on :voice do |request| # Отправка отправленного голосового сообщения обратно пользователю # request.reply.voice(request[:MediaId])

voice_id = request[:MediaId]
# Доступно только для сервисного аккаунта и должно быть активировано в панели управления.
recognition = request[:Recognition]
request.reply.text "#{voice_id} #{recognition}"

end

Когда пользователь отправляет видео

on :video do |request| nickname = wechat.user(request[:FromUserName])['nickname'] # Вызов API WeChat для получения имени пользователя request.reply.video(request[:MediaId], title: 'Эхо', description: "Получено от #{nickname}") # Отправка отправленного видео обратно пользователю end

Когда пользователь отправляет сообщение местоположения с меткой

on :label_location do |request| request.reply.text("Метка: #{request[:Label]} Координата X: #{request[:Location_X]} Координата Y: #{request[:Location_Y]} Масштаб: #{request[:Scale]}") end

Когда пользователь отправляет сообщение местоположения

on :location do |request| request.reply.text("Широта: #{request[:Latitude]} Долгота: #{request[:Longitude]} Точность: #{request[:Precision]}") end

on :event, with: 'unsubscribe' do |request| request.reply.success # Пользователь не сможет получить это сообщение end # Когда пользователь заходит в приложение / агентское приложение on :event, with: 'enter_agent' do |request| request.reply.text "#{request[:FromUserName]} сейчас находится в агентском приложении" end # Когда=batch_job "обновление пользователя (инкрементальная)" завершена. on :batch_job, with: 'sync_user' do |request, batch_job| request.reply.text "задача sync_user #{batch_job[:JobId]} завершена, код возврата #{batch_job[:ErrCode]}, сообщение возврата #{batch_job[:ErrMsg]}" end # Когда=batch_job "Замена пользователя (полная синхронизация)" завершена. on :batch_job, with: 'replace_user' do |request, batch_job| request.reply.text "задача replace_user #{batch_job[:JobId]} завершена, код возврата #{batch_job[:ErrCode]}, сообщение возврата #{batch_job[:ErrMsg]}" end

Когда=batch_job "Приглашение пользователя" завершено.

on :batch_job, with: 'invite_user' do |request, batch_job| request.reply.text "задача invite_user #{batch_job[:JobId]} завершена, код возврата #{batch_job[:ErrCode]}, сообщение возврата #{batch_job[:ErrMsg]}" end

Когда=batch_job "Замена отдела (полная синхронизация)" завершена.

on :batch_job, with: 'replace_party' do |request, batch_job| request.reply.text "задача replace_party #{batch_job[:JobId]} завершена, код возврата #{batch_job[:ErrCode]}, сообщение возврата #{batch_job[:ErrMsg]}" end

Уведомление о завершении массовой отправки задачи

on :event, with: 'masssendjobfinish' do |request| # https://mp.weixin.qq.com/wiki?action=doc&id=mp1481187827_i0l21&t=0.03571905015619936#8 request.reply.success # запрос является хэшем результата XML. end

Клиент соглашается вызвать событие архивирования чата внешнего контакта

on :change_external_contact do |request| # https://open.work.weixin.qq.com/api/doc/90000/90135/92005 request.reply.success # запрос является хэшем результата XML. end

Возврат события мониторинга аудита

on :msgaudit_notify do |request| # https://open.work.weixin.qq.com/api/doc/90000/90135/95039 request.reply.success # запрос является хэшем результата XML. end # Если выше нет совпадений, будет использоваться ниже on :fallback, respond: 'сообщение по умолчанию' end

 Основной важный оператор здесь  это `wechat_responder`. 
 Все остальное представляет собой просто DSL:
 ```ruby
on <message_type> do |message|
 message.reply.text "текст"
end

Этот блок кода выполняется для ответа на сообщение пользователя. Следующие типы сообщений поддерживаются в настоящее время:

  • :текст — текстовое сообщение, используя :with для совпадения с содержанием текста, как в on(:текст, with:'помощь'){|сообщение, содержание| ...}
  • :изображение — изображение сообщение
  • :голос — голосовое сообщение
  • :короткое_видео — короткое видео сообщение
  • :видео — видео сообщение
  • :метка_местоположение — местоположение сообщение с меткой
  • :ссылка — ссылка сообщение
  • :событие — событие сообщение, используя :with для совпадения конкретного события, поддерживаются регулярные выражения для совпадения аналогично текстовому сообщению.
  • :клика — виртуальное событие сообщение, WeChat всё ещё отправляет событие сообщение, но библиотеки будут отображаться как событие нажатия меню.
  • :просмотра — виртуальное событие просмотра страницы, WeChat всё ещё отправляет событие сообщение, но библиотеки будут отображаться как событие просмотра страницы меню.
  • :скана — виртуальное событие сканирования, WeChat всё ещё отправляет событие сообщение, но библиотеки будут отображаться как событие сканирования.
- :локация виртуальное местоположение сообщение
- :обратный_вызов по умолчанию сообщение, когда ни один другой обработчик входящих сообщений не может его обработать, будет использоваться как обратный вызов обработчика### Передача в службу поддержки клиентов```ruby
class WechatsController < ActionController::Base
 # Когда ни один другой обработчик сообщений не может принять входящее сообщение, будет передана в службу поддержки клиентов.
 on :fallback do |message|
   message.reply.transfer_customer_service
 end
end

Внимание: не устанавливайте по умолчанию текстовый ответ, если вы хотите использовать множественную службу поддержки клиентов, иначе это приведёт к невозможности передачи текстовых сообщений.

Установка стандартного ответа, повторять не чаще чем раз в неделю

class WechatsController < ActionController::Base
  on :fallback do |message|
    Rails.logger.debug "YouApp_ToUserName: #{message.message_hash['FromUserName']}"
    session = WechatSession.find_by(openid: message.message_hash['FromUserName'])
    return message.reply.success if session.present? && session.greeting_time.present? && session.greeting_time >= 1.week.ago

    images_path = Rails.root.join('public', 'images', 'default_help.jpg')
    media_id = Wechat.api.media_create('image', images_path)['media_id']
    if session.present? && session.reload
      # сгенерировать миграцию: add_column :wechat_sessions, :greeting_time, :datetime
      session.update(greeting_time: Time.current)
    end
    message.reply.image(media_id)
  end
end

Уведомления

  • wechat.responder.after_create данные включают запрос <Wechat::Message> и ответ <Wechat::Message>.

Пример:

ActiveSupport::Notifications.subscribe('wechat.responder.after_create') do |name, started, finished, unique_id, data|
  WechatLog.create(request: data[:request], response: data[:response])
end

Известные проблемы* Иногда корпоративный аккаунт не может получить сообщение меню из-за того, что сервер Tencent не может разрешить DNS; поэтому использование IP как URL обратного вызова более надёжно, но это никогда не происходит при отправке пользователем текстовых сообщений.

  • Корпоративная замена пользователей использует файл в формате CSV, но если вы используете скачанный шаблон напрямую, он не работает; необходимо открыть CSV файл в Excel, затем сохранить его снова в формате CSV, кажется, Tencent поддерживает только формат файла CSV, сохранённого через Excel.
  • Если вы используете unicorn за nginx и https, вам нужно установить trusted_domain_fullname и указать его на https, иначе это будет http и приведёт к недействительной подписи в JS-SDK.

Введение

API, обработка команд и сообщений для WeChat в Rails. Развернуть Свернуть
Ruby и 2 других языков
MIT
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/Eric-Guo-wechat.git
git@api.gitlife.ru:oschina-mirror/Eric-Guo-wechat.git
oschina-mirror
Eric-Guo-wechat
Eric-Guo-wechat
main