Botframework V4: местоположение Messenger, телефон и электронная почта

Это еще один bash & amp; python гибридный ответ. Я опубликовал этот ответ, потому что хотел обработать более сложный вывод JSON, но, уменьшив сложность моего приложения bash. Я хочу открыть следующий объект JSON из http://www.arcgis.com/sharing/rest/info?f=json в bash:

{
  "owningSystemUrl": "http://www.arcgis.com",
  "authInfo": {
    "tokenServicesUrl": "https://www.arcgis.com/sharing/rest/generateToken",
    "isTokenBasedSecurity": true
  }
}

Несмотря на то, что этот подход увеличивает сложность функции Python, использование bash упрощается:

function jsonGet {
  python -c 'import json,sys
o=json.load(sys.stdin)
k="'$1'"
if k != "":
  for a in k.split("."):
    if isinstance(o, dict):
      o=o[a] if a in o else ""
    elif isinstance(o, list):
      if a == "length":
        o=str(len(o))
      elif a == "join":
        o=",".join(o)
      else:
        o=o[int(a)]
    else:
      o=""
if isinstance(o, str) or isinstance(o, unicode):
  print o
else:
  print json.dumps(o)
'
}

curl -s http://www.arcgis.com/sharing/rest/info?f=json | jsonGet
curl -s http://www.arcgis.com/sharing/rest/info?f=json | jsonGet authInfo
curl -s http://www.arcgis.com/sharing/rest/info?f=json | jsonGet authInfo.tokenServicesUrl

Вывод вышеупомянутого скрипта:

Я добавил поддержку массивов, поэтому вы можете использовать .length, и если источник представляет собой строковый массив, вы можете использовать .join:

curl -s http://www.arcgis.com/sharing/rest/portals/self?f=pjson | jsonGet defaultBasemap.baseMapLayers.length
curl -s http://www.arcgis.com/sharing/rest/portals/self?f=pjson | jsonGet defaultBasemap.baseMapLayers.0.resourceInfo.tileInfo.lods
curl -s http://www.arcgis.com/sharing/rest/portals/self?f=pjson | jsonGet defaultBasemap.baseMapLayers.0.resourceInfo.tileInfo.lods.length
curl -s http://www.arcgis.com/sharing/rest/portals/self?f=pjson | jsonGet defaultBasemap.baseMapLayers.0.resourceInfo.tileInfo.lods.23

Какие выходы:

  • 1
  • [{"scale": 591657527.591555, "resolution": 156543.03392800014, "level": 0}, {"scale": 295828763.795777, "resolution": 78271.51696399994, "level": 1}, {"scale": 147914381.897889, "resolution": 39135.75848200009, "level": 2}, {"scale": 73957190.948944, "resolution": 19567.87924099992, "level": 3}, {"scale": 36978595.474472, "resolution" : «Уровень»: 4}, {«scale»: 18489297.737236, «resolution»: 4891.96981024998, «level»: 5}, {«scale»: 9244648.868618, «resolution»: 2445.98490512499, «level»: 6}, {"scale": 4622324.434309, "resolution": 1222.992452562495, "level": 7}, {"scale": 2311162.217155, "resolution": 611.4962262813797, "level": 8}, {"scale": 1155581.108577, "resolution" : 305.74811314055756, "level": 9}, {"scale": 577790.554289, "resolution": 152.87405657041106, "level": 10}, {"scale": 288895.277144, "resolution": 76.43702828507324, "level": 11}, {"scale": 144447.638572, "resolution": 38.21851414253662, "level": 12}, {"scale": 72223.819286, "resolution": 19.10925707126831, "level": 13}, {"scale": 36111.909643, "resolution" : 9.554628535634155, "level": 14}, {"scale": 18055.954822, "resolution": 4.77731426794937, "level ": 15}, {" scale ": 9027.977411," resolution ": 2.388657133974685," level ": 16}, {" scale ": 4513.988705," resolution ": 1.1943285668550503," level ": 17}, {" scale ": 2256.994353, «разрешение»: 0,5971642835598172, «уровень»: 18}, {«шкала»: 1128,497176, «разрешение»: 0,29858214164761665, «уровень»: 19}, {«шкала»: 564,248588, «разрешение»: 0.14929107082380833, уровень ": 20}, {" scale ": 282.124294," resolution ": 0.07464553541190416," level ": 21}, {" scale ": 141.062147," resolution ": 0.03732276770595208," level ": 22}, {" scale ": 70.5310735, «разрешение»: 0,01866138385297604, «уровень»: 23}]
  • 24
  • {"scale": 70.5310735, "resolution": 0.01866138385297604, "level": 23}

0
задан user10860402 26 March 2019 в 09:01
поделиться

1 ответ

Вам необходимо предоставить специальный валидатор, если вы хотите захватить местоположение пользователя с помощью быстрого ответа о местоположении Facebook Messenger в текстовом или вложенном приглашении - я бы рекомендовал использовать текстовое приглашение.

Конструктор

Создайте свой водопад и добавьте свои подсказки в стек диалогов в вашем конструкторе. Не забудьте добавить пользовательский валидатор в текстовое приглашение; в противном случае бот будет неоднократно запрашивать у пользователя его местоположение, так как он ожидает текстовое значение, которое быстрый ответ не предоставляет.

public MultiTurnPromptsBot(MultiTurnPromptsBotAccessors accessors)
{
    ...
    // This array defines how the Waterfall will execute.
    var waterfallSteps = new WaterfallStep[]
    {
        PromptForLocation,
        CaptureLocation,
    };
    ...
    // Add named dialogs to the DialogSet. These names are saved in the dialog state.
    _dialogs.Add(new WaterfallDialog("details", waterfallSteps));
    _dialogs.Add(new TextPrompt("location", LocationPromptValidatorAsync));

}

Валидатор местоположения

В пользовательском валидаторе вы можете проверить входящее действие для объекта местоположения, который находится в свойстве сущностей действия. Если у действия нет местоположения, вы можете вернуть false, и в запросе у пользователя снова будет указано его местоположение; в противном случае он перейдет к следующему шагу.

public Task<bool> LocationPromptValidatorAsync(PromptValidatorContext<string> promptContext, CancellationToken cancellationToken)
{
    var activity = promptContext.Context.Activity;
    var location = activity.Entities?.FirstOrDefault(e => e.Type == "Place");
    if (location != null) {
        return Task.FromResult(true);
    }
    return Task.FromResult(false);
}  

Запрос местоположения

Как и в приведенном выше фрагменте кода, вы можете добавить быстрый ответ Facebook Messenger к данным канала ответа.

private static async Task<DialogTurnResult> PromptForLocation(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    Activity reply = stepContext.Context.Activity.CreateReply();
    reply.Text = "What is your location?";
    reply.ChannelData = JObject.FromObject( new {

        quick_replies = new object[]
        {
            new
            {
                content_type = "location",
            },
        },
    });

    return await stepContext.PromptAsync("location", new PromptOptions { Prompt = reply }, cancellationToken);
}

Местоположение захвата

Здесь вы можете захватить местоположение пользователя, чтобы использовать его как угодно.

private async Task<DialogTurnResult> CaptureLocation(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{

    var activity = stepContext.Context.Activity;
    var location = activity.Entities?.FirstOrDefault(e => e.Type == "Place");
    if (location != null) {
        var latitude = location.Properties["geo"]?["latitude"].ToString();
        var longitude = location.Properties["geo"]?["longitude"].ToString();

        await stepContext.Context.SendActivityAsync($"Latitude: {latitude} Longitude: {longitude}");

    }
    // WaterfallStep always finishes with the end of the Waterfall or with another dialog, here it is the end.
    return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
}

Надеюсь, это поможет!

0
ответ дан tdurnford 26 March 2019 в 09:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: