質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
freeeAPI

freeeAPIは「会計freee」「人事労務freee」など、freeeが提供する各サービスに実装されている RESTful API です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

1回答

1950閲覧

会計freee 仕訳帳APIをkintone Javascriptを使って取得すると文字化けしてしまう

MJNKG

総合スコア1

freeeAPI

freeeAPIは「会計freee」「人事労務freee」など、freeeが提供する各サービスに実装されている RESTful API です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2021/05/26 10:49

実現したいこと

kintone Javascriptカスタマイズで実行しているコードから、会計freeeの仕訳帳APIを使用し仕訳帳データを取得しkintoneに書き込みたい。

発生している問題

仕訳帳取得API(/api/1/journals/reports/{id}/download)のレスポンスとしては成功はしていますが、文字化けしてしまっています。
関係あるかは定かではありませんが、/api/1/journalsの文字コードはutf-8で、
/api/1/journals/reports/{id}/downloadの文字コードはsjisになっていることがresponse headerから分かりました。

response status 200 response header { "Transfer-Encoding": "chunked", "X-Request-Id": "bpl06e8avvojvsnu334g", "X-Content-Type-Options": "nosniff", "X-Runtime": "0.370447", "Connection": "keep-alive", "X-Download-Options": "noopen", "X-Permitted-Cross-Domain-Policies": "none", "Content-Transfer-Encoding": "binary", "Date": "Wed, 26 May 2021 09:41:28 GMT", "X-Frame-Options": "SAMEORIGIN", "Referrer-Policy": "strict-origin-when-cross-origin", "Cache-Control": "private", "ETag": "W/\"dc33cef6d77f4d571d9ded7c2c7c28cd\"", "Content-Disposition": "attachment; filename=\"ä»è¨³å¸³ ï¼2019å¹´01æ~2019å¹´01æï¼.csv\"", "X-XSS-Protection": "1; mode=block", "X-Freee-Request-Id": "bpl06e8avvojvsnu334g", "Content-Type": "text/csv; charset=sjis; header=present" } response body "","�����","�ؕ�����Ȗ�","�ؕ����z","�ؕ��ŋ敪","�ؕ��i��","�ؕ�����","�ؕ�����","�ݕ�����Ȗ�","�ݕ����z","�ݕ��ŋ敪","�ݕ��i��","�ݕ�����","�ݕ�����","�����","�E�v","���Z�����d��","�d��ԍ�","�ؕ������","�ݕ������","�Ǘ��ԍ�","�쐬����","�ؕ�����ȖڃR�[�h","�ݕ�����ȖڃR�[�h","�X�V����","���F��","���F��","���F����","�쐬��" "1","2019/01/31","�ݓ|�J���z(��)","235201","�ΏۊO","","","","�ݓ|������(��)","235201","�ΏۊO","","","","","�ݓ|�������ݒ�","0","9013101","","","","2020-03-24 14:23","787","199","2020-03-24 14:23","�Ȃ�","","","User" "2","2019/01/31","�O����p","120344","�ΏۊO","","","","�ی���","120344","�ΏۊO","","","","","�O�����΍Еی�","0","9013102","","","","2020-03-24 14:23","175","770","2020-03-24 14:23","�Ȃ�","","","User"

該当のソースコード

javascript

1 2const freeeJournalsDownloadRequest = (accessToken, companyId) => { 3 return new kintone.Promise( 4 resolve => { 5 swal({ 6 content: { 7 element: 'input', 8 attributes: { 9 placeholder: 'Please enter the start date for getting journals. (e.g. 20200101)' 10 } 11 } 12 }) 13 .then(response => { 14 if (!response) { 15 resolve(); 16 return; 17 } 18 sessionStorage.setItem('startDate', response); 19 swal({ 20 content: { 21 element: 'input', 22 attributes: { 23 placeholder: 'Please enter the end date for getting journals. (e.g. 20201231)' 24 } 25 } 26 }) 27 .then(async response => { 28 if (!response) { 29 resolve(); 30 return; 31 } 32 let startDate = sessionStorage.getItem('startDate'); 33 let endDate = response; 34 sessionStorage.removeItem('startDate'); 35 let header = { 36 'Authorization': 'Bearer ' + accessToken 37 }; 38 // resolve(kintone.proxy('https://api.freee.co.jp/api/1/journals?company_id=' + companyId + '&download_type=generic&visible_tags[]=partner&visible_tags[]=item&visible_tags[]=tag&visible_tags[]=section&visible_tags[]=description&visible_tags[]=wallet_txn_description&visible_tags[]=segment_1_tag&visible_tags[]=segment_2_tag&visible_tags[]=segment_3_tag&start_date=' + startDate + '&end_date=' + endDate, 'GET', header, {})); 39 resolve(kintone.proxy('https://api.freee.co.jp/api/1/journals?company_id=' + companyId + '&download_type=generic&visible_tags[]=partner&visible_tags[]=item&visible_tags[]=tag&visible_tags[]=section&visible_tags[]=description&visible_tags[]=wallet_txn_description&start_date=' + startDate + '&end_date=' + endDate, 'GET', header, {})); 40 }) 41 }) 42 } 43 ) 44} 45 46const checkRepeatedlyFreeeJournalsDownloadStatus = (accessToken, companyId, freeeJournalsDownloadRequestId) => { 47 return new kintone.Promise( 48 resolve => { 49 let statusCheckInterval = setInterval(async () => { 50 let freeeJournalsDownloadStatus = await checkFreeeJournalsDownloadStatus(accessToken, companyId, freeeJournalsDownloadRequestId); 51 if (freeeJournalsDownloadStatus[1] != 200) { 52 swal('Error', String(freeeJournalsDownloadStatus[1]), 'error'); 53 clearInterval(statusCheckInterval); 54 } 55 if (freeeJournalsDownloadStatus[1] == 200) { 56 if (JSON.parse(freeeJournalsDownloadStatus[0]).journals.status == 'uploaded') { 57 clearInterval(statusCheckInterval); 58 let freeeJournalsDownloadResponse = await freeeJournalsDownload(accessToken, companyId, freeeJournalsDownloadRequestId); 59 resolve(freeeJournalsDownloadResponse); 60 } 61 } 62 }, 10000); 63 } 64 ) 65} 66 67const checkFreeeJournalsDownloadStatus = (accessToken, companyId, freeeJournalsDownloadRequestId) => { 68 return new kintone.Promise( 69 resolve => { 70 let header = { 71 'Authorization': 'Bearer ' + accessToken 72 }; 73 resolve(kintone.proxy('https://api.freee.co.jp/api/1/journals/reports/' + freeeJournalsDownloadRequestId + '/status?company_id=' + companyId, 'GET', header, {})); 74 } 75 ) 76} 77 78const freeeJournalsDownload = (accessToken, companyId, freeeJournalsDownloadRequestId) => { 79 return new kintone.Promise( 80 resolve => { 81 let header = { 82 'Authorization': 'Bearer ' + accessToken 83 }; 84 resolve(kintone.proxy('https://api.freee.co.jp/api/1/journals/reports/' + freeeJournalsDownloadRequestId + '/download?company_id=' + companyId, 'GET', header, {}, (body, status, headers) => { 85 console.log(status); 86 console.log(headers); 87 console.log(body); 88 })); 89 } 90 ) 91} 92 93 94 95const selectPlByProjectMenu = async (menuNumber, recordId, companyId) => { 96 if (menuNumber == 1) { 97 let accessToken = await validateExpirationDate(recordId); 98 let freeeJournalsDownloadRequestResponse = await freeeJournalsDownloadRequest(accessToken, companyId); 99 if (freeeJournalsDownloadRequestResponse[1] != 202) { 100 swal('Error', String(freeeJournalsDownloadRequestResponse[1]), 'error'); 101 } 102 if (freeeJournalsDownloadRequestResponse[1] == 202) { 103 let freeeJournalsDownloadRequestId = JSON.parse(freeeJournalsDownloadRequestResponse[0]).journals.id; 104 await checkRepeatedlyFreeeJournalsDownloadStatus(accessToken, companyId, freeeJournalsDownloadRequestId); 105 // console.log(freeeJournalsData); 106 // console.log(freeeJournalsData[0]); 107 // console.log(JSON.parse(freeeJournalsData[0])); 108 } 109 } 110}

試したこと

freee developers communityを参照しましたが、2018-2019年の投稿では解決方法がないことは確認済みです。
また、API Referenceで/api/1/journals/api/1/journals/reports/{id}/downloadを行った結果も変わらず文字化けをしておりました。

補足情報

API Referenceで行ったテストについて記載しておきます。

/api/1/journals <Request URL> https://api.freee.co.jp/api/1/journals?download_type=generic&company_id=1234567&visible_tags[]=partner&start_date=2019-01-01&end_date=2019-01-31 <Response body> { "journals": { "id": 13593676, "messages": [ "ID:13593676 でリクエストを受け付けました。" ], "company_id": 1234567, "download_type": "generic", "start_date": "2019-01-01", "end_date": "2019-01-31", "visible_tags": [ "partner" ], "status_url": "https://api.freee.co.jp/api/1/journals/reports/13593676/status", "up_to_date": true, "up_to_date_reasons": [] } } <Response headers> cache-control: no-cache content-type: application/json; charset=utf-8 /api/1/journals/reports/{id}/download <Request URL> https://api.freee.co.jp/api/1/journals/reports/13593676/download?company_id=1234567 <Response body> "","�����","�ؕ�����Ȗ�","�ؕ����z","�ؕ��ŋ敪","�ݕ�����Ȗ�","�ݕ����z","�ݕ��ŋ敪","�����","���Z�����d��","�d��ԍ�","�ؕ������","�ݕ������","�Ǘ��ԍ�","�쐬����","�ؕ�����ȖڃR�[�h","�ݕ�����ȖڃR�[�h","�X�V����","���F��","���F��","���F����","�쐬��" "1","2019/01/31","�ݓ|�J���z(��)","235201","�ΏۊO","�ݓ|������(��)","235201","�ΏۊO","","0","9013101","","","","2020-03-24 14:23","787","199","2020-03-24 14:23","�Ȃ�","","","User" "2","2019/01/31","�O����p","120344","�ΏۊO","�ی���","120344","�ΏۊO","","0","9013102","","","","2020-03-24 14:23","175","770","2020-03-24 14:23","�Ȃ�","","","User" <Response headers> cache-control: private content-type: text/csv; charset=sjis; header=present

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

APIリファレンスとコミュニティの質疑応答を見てきましたが、freee側はsjis固定の仕様でutf-8に対応する気はないようです。

kintone側でレスポンスをバイナリで扱えればTextDecoderでワンチャンあるかと思いましたが、現在のproxyの仕様ではそういうこともできないようです。(必ず文字列で返ってくる模様)

freee側の改修は見込めなさそうなので、サイボウズ側にproxyのレスポンスボディをblobでも取得できるようなリクエストを送ってみたらどうでしょうか。

その他の解決策としては、自前でfreeeのレスポンス内容をsjisからutf8に変換する中継サーバを用意するとかぐらいしか思いつきません。

投稿2021/05/26 18:41

hope_mucci

総合スコア4447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MJNKG

2021/05/26 23:19 編集

hope_mucci さん ご回答ありがとうございます。 「自前でfreeeのレスポンス内容をsjisからutf8に変換する中継サーバを用意する」 やはりこういったことになりますよね...。 cybozu側の確認もして頂いて、ありがとうございました。
hope_mucci

2021/05/27 04:21

まあ、仕方ないでしょう。 そもそもjounals/downdoadはjavascirptで後続処理をする想定のAPIではないですし(csvをダウンロードしてサーバ側で自動処理させるため) Web画面のダウンロードではutf-8を選択できるのに何でAPIではできないんだという憤りも良くわかります。本当になんでなんでしょうね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問