Esempio n. 1
0
        private async Task <IEnumerable <long> > UploadMediaAsync(KintoneWebhookRequest kintoneRequest, Tokens tokens)
        {
            try
            {
                var list = new List <long>();

                foreach (var attachment in kintoneRequest.Record.添付ファイル.Value)
                {
                    var content = $"Name={attachment.Name},FileKey={attachment.FileKey},Size={attachment.Size},ContentType={attachment.ContentType}";
                    _logger.LogInformation(content);

                    var url = $"{_kintoneSettings.Value.ServiceUrl}k/v1/file.json?fileKey={attachment.FileKey}";
                    using var client = new HttpClient();
                    var request = new HttpRequestMessage(HttpMethod.Get, url);
                    request.Headers.Add("X-Cybozu-API-Token", _kintoneSettings.Value.ApiToken);
                    var response = await client.SendAsync(request);

                    var stream = await response.Content.ReadAsStreamAsync();

                    var mediaUploadResult = await tokens.Media.UploadAsync(stream);

                    list.Add(mediaUploadResult.MediaId);
                }
                return(list);
            }
            catch (Exception ex)
            {
                _logger.LogError($"{ex.Message}");
                _logger.LogError($"{ex.StackTrace}");

                throw;
            }
        }
Esempio n. 2
0
        public async Task <IActionResult> Post([FromBody] KintoneWebhookRequest kintoneRequest)
        {
            var requestContent = $"Url={kintoneRequest.Url},App.Id={kintoneRequest.App.Id}" +
                                 $",承認ステータス={kintoneRequest.Record.承認ステータス.Value}" +
                                 $",Type={kintoneRequest.Type},Twitter投稿済={string.Join(",", kintoneRequest.Record.Twitter投稿済.Value)}" +
                                 $",Twitter投稿メッセージ={kintoneRequest.Record.Twitter投稿メッセージ.Value}" +
                                 $",投稿内容={kintoneRequest.Record.投稿内容.Value}";

            _logger.LogInformation(requestContent);

            //Webhookで来たJsonのチェック。指定したサービス・アプリ・イベント以外はUnAuthorizedで返す
            if (!kintoneRequest.Url.StartsWith(_kintoneSettings.Value.ServiceUrl))
            {
                return(Unauthorized());
            }
            if (kintoneRequest.App.Id != _kintoneSettings.Value.AppId)
            {
                return(Unauthorized());
            }
            if (kintoneRequest.Type != "UPDATE_RECORD")
            {
                return(Unauthorized());
            }

            //承認以外は何もしない
            if (kintoneRequest.Record.承認ステータス.Value != "承認")
            {
                return(Ok());
            }

            //投稿済は何もしない
            if (kintoneRequest.Record.Twitter投稿済.Value.Contains("投稿済"))
            {
                return(Ok());
            }

            //Twitter投稿メッセージが何か入っていたら、何もしない(エラー後の更新でループすることの回避)
            if (!string.IsNullOrEmpty(kintoneRequest.Record.Twitter投稿メッセージ.Value))
            {
                return(Ok());
            }

            //Twitterの認証情報セット
            var apiKey            = _twitterSettings.Value.ApiKey;
            var apiSecret         = _twitterSettings.Value.ApiSecret;
            var accessToken       = _twitterSettings.Value.AccessToken;
            var accessTokenSecret = _twitterSettings.Value.AccessTokenSecret;
            var tokens            = CoreTweet.Tokens.Create(apiKey, apiSecret, accessToken, accessTokenSecret);

            //Twitterへ投稿
            try
            {
                //メディアを先にアップロード
                var mediaIdList = await UploadMediaAsync(kintoneRequest, tokens);

                //メディア付きでTweet
                var mediaIds      = mediaIdList.Any() ? mediaIdList.ToArray() : null;
                var tweetResponse = tokens.Statuses.Update(status: $"{kintoneRequest.Record.投稿内容.Value}", media_ids: mediaIds);
                _logger.LogInformation($"Twitter投稿OK。Id:{tweetResponse.Id},CreatedAt:{tweetResponse.CreatedAt}");
            }
            catch (TwitterException ex)
            {
                var error        = ex.Errors.First();
                var errorMessage = $"{error.Code}:{error.Message}";
                _logger.LogWarning(errorMessage);

                //エラーをKintoneに反映
                var tweetErrorJson = JsonSerializer.Serialize(new NotifyErrorRequestBody(kintoneRequest.App.Id, kintoneRequest.Record.レコード番号.Value, errorMessage));
                await NotifyAsync(tweetErrorJson);

                //キャッチできるエラーなので、200で返す
                return(Ok());
            }
            catch (Exception ex)
            {
                var errorMessage = ex.Message;

                //stacktraceはサーバにはstacktraceも出す
                _logger.LogError($"{errorMessage}\r\n{ex.StackTrace}");

                //エラーをKintoneに反映
                var jsonError = JsonSerializer.Serialize(new NotifyErrorRequestBody(kintoneRequest.App.Id, kintoneRequest.Record.レコード番号.Value, errorMessage));
                await NotifyAsync(jsonError);

                //想定していないエラーなので、500で返す
                return(new StatusCodeResult(StatusCodes.Status500InternalServerError));
            }

            //投稿結果をKintoneに反映
            var json = JsonSerializer.Serialize(new NotifySuccessRequestBody(kintoneRequest.App.Id, kintoneRequest.Record.レコード番号.Value));

            if (await NotifyAsync(json))
            {
                return(Ok());
            }
            return(new StatusCodeResult(StatusCodes.Status500InternalServerError));
        }